因此,我刚刚看完有关Python全局解释器锁(GIL)http://blip.tv/file/2232410的演讲。
要点是,GIL是用于单核系统的不错的设计(Python本质上将线程处理/调度留给了操作系统)。但是,这可能会在多核系统上造成严重后果,最终导致IO密集型线程被CPU密集型线程严重阻塞,上下文切换的开销,ctrl- C问题[*]等。
因此,由于GIL限制了我们只能在一个CPU上基本执行Python程序,所以我的想法是为什么不接受它,而只是在Linux上使用任务集将程序的亲和力设置为系统上的某个核心/ cpu(尤其是在在多核系统上运行的多个Python应用)?
所以最终我的问题是:是否有人尝试在Linux上将Python和Python应用程序一起使用任务集(尤其是在Linux系统上运行多个应用程序,以便多个内核可以与绑定到特定内核的一个或两个Python应用程序一起使用时),如果是的话,该怎么办?是结果吗?这值得吗?对于某些工作负载,情况是否会变得更糟?我打算这样做并对其进行测试(基本上看该程序是否需要花费更多或更少的时间来运行),但希望能从其他人那里得到您的经验。
另外:David Beazley(在链接的视频中进行演讲的人)指出,某些C / C ++扩展手动释放GIL锁定,如果这些扩展针对多核进行了优化(即科学或数字数据分析等),则而不是使用多核的数字处理优势,因为扩展仅限于单个核(因此可能会显着降低程序速度),因此实际上会遭到破坏。另一方面,如果您不使用此类扩展名
我不使用多处理模块的原因是(在这种情况下)程序的一部分受到了网络I / O的严格限制(HTTP请求),因此拥有工作线程池是从根本上降低性能的一种好方法一个线程触发一个HTTP请求,然后由于它正在等待I / O而放弃了GIL,而另一个线程可以做到这一点,因此该程序的一部分可以轻松地运行100个以上的线程,而又不会对CPU造成很大的伤害,而让我实际使用可用的网络带宽。至于无堆栈Python / etc,我对重写程序或替换我的Python堆栈并不太感兴趣(可用性也将是一个问题)。
[*]只有主线程可以接收信号,因此,如果您发送ctrl-C,Python解释器基本上会尝试使主线程运行,以便它可以处理信号,但是由于它不能直接控制运行哪个线程(它基本上由操作系统决定),它基本上告诉操作系统保持切换线程,直到最终到达主线程为止(如果您不走运,可能需要一段时间)。
我从未听说有人使用Taskset来提高Python的性能。这并不意味着您的情况不会发生,而是一定要发布您的结果,以便其他人可以批评您的基准测试方法并提供验证。
不过,就我个人而言,我将使用消息队列将I / O线程与CPU绑定的线程解耦。这样,您的前端现在完全受网络I / O约束(有些使用HTTP接口,有些使用消息队列接口),非常适合您的线程情况。然后,CPU密集型进程可以使用多进程,也可以只是单个进程,等待工作到达消息队列。
从长远来看,您可能还需要考虑用Twisted或诸如eventlet之类的东西来替换线程化的I / O前端,因为即使它们对性能没有帮助,它们也应该提高可伸缩性。您的后端现在已经可以扩展,因为您可以根据需要在任意数量的计算机+ CPU上运行消息队列。