所以我刚刚看完了关于 Python Global Interpreter Lock (GIL) http://blip.tv/file/2232410的演讲。
它的要点是 GIL 对于单核系统来说是一个非常好的设计(Python 基本上将线程处理/调度留给了操作系统)。但这在多核系统上可能会严重适得其反,最终导致 IO 密集型线程被 CPU 密集型线程严重阻塞、上下文切换的代价、ctrl-C 问题 [*] 等等。
因此,由于 GIL 限制我们基本上只能在一个 CPU 上执行 Python 程序,我的想法是为什么不接受这一点并简单地使用 Linux 上的任务集来将程序的亲和性设置为系统上的某个核心/cpu(尤其是在在多核系统上运行多个 Python 应用程序)?
所以最终我的问题是:有没有人尝试过在 Linux 上使用带有 Python 应用程序的任务集(尤其是在 Linux 系统上运行多个应用程序时,以便可以将多个内核与绑定到特定内核的一个或两个 Python 应用程序一起使用),如果是这样的话结果是什么?值得吗?对于某些工作负载,它会使情况变得更糟吗?我计划这样做并对其进行测试(基本上是看看程序是否需要更多或更少的时间来运行),但我很想听听其他人的经验。
补充:David Beazley(在链接视频中发表演讲的人)指出,一些 C/C++ 扩展手动释放 GIL 锁,如果这些扩展针对多核(即科学或数字数据分析等)进行了优化,那么而不是获得多核的好处来处理数字,扩展将被有效地削弱,因为它仅限于单核(因此可能会显着减慢您的程序速度)。另一方面,如果您不使用这样的扩展
我不使用多处理模块的原因是(在这种情况下)程序的一部分是严重的网络 I/O 绑定(HTTP 请求),因此拥有一个工作线程池是一种很好的方式来提高性能,因为一个线程触发一个 HTTP 请求,然后因为它在等待 I/O 放弃了 GIL,另一个线程可以做到这一点,所以程序的一部分可以轻松运行 100 多个线程而不会对 CPU 造成太大伤害,让我实际使用可用的网络带宽。至于无堆栈 Python/etc,我对重写程序或替换我的 Python 堆栈并不太感兴趣(可用性也是一个问题)。
[*] 只有主线程可以接收信号,所以如果你发送一个 ctrl-C,Python 解释器基本上会尝试让主线程运行以便它可以处理信号,但是因为它不直接控制运行哪个线程(这留给操作系统)它基本上告诉操作系统继续切换线程,直到它最终到达主线程(如果你不走运可能需要一段时间)。