所以,我刚看完上的Python全局解释器锁(GIL)这次谈话 http://blip.tv/文件/ 2232410

它的要点是,GIL是用于单核系统相当不错的设计(Python的基本上离开该线程处理/调度到操作系统)。但是,这可以严重地适得其反多核系统和你最终IO密集线程正在由CPU密集型的线程重阻塞,上下文切换为代价,将CTRL-C问题[*]等。

如此以来,GIL限制我们一个CPU上基本上执行Python程序我的想法是为什么不接受这一点,只需使用taskset的Linux上节目的亲和力设置为某些核心/ CPU的系统上(特别是在与多核系统上运行的多个应用程序的Python)的情况?

所以,最后我的问题是这样的:有没有人使用taskset的Linux上与Python应用(特别是运行Linux系统上的多个应用程序时,使多个内核可以与绑定到特定核心的一个或两个Python应用中使用)尝试和如果是这样结果是什么?是它的价值呢?它使事情对某些工作负载更糟糕?我打算这样做,并对其进行测试(主要看是否程序都将或多或少地运行时间),但很乐意听到别人以您的经验。

增加:大卫比兹利(所述人给予在链接的视频通话)指出,一些C / C ++扩展手动释放GIL锁定,并且如果这些扩展为多芯(即科学或数值数据分析/等优化。)然后,而不是越来越多核心的好处啃延伸将有效削弱,它仅限于一个单一的芯数(从而有可能降低显著减慢你的程序)。在另一方面,如果不使用扩展,如本

我不使用多处理模块的原因是(在这种情况下)中的程序的一部分,在很大程度上网络I / O绑定(HTTP请求),所以具有工作线程池是挤压表现出来的好方法因为一个线程打完一个HTTP请求框,然后因为它是等待I / O放弃了GIL和另一个线程可以做的事情,所以程序的一部分可以轻松地运行100多个线程不伤害CPU的多,让我实际使用的网络带宽是可用的。至于无堆栈的Python /等我不是重写程序或更换我的Python堆栈(可用性也将是一个问题)过分感兴趣。

[*]只有主线程可以接收信号,因此,如果你发送一个CTRL-C Python解释基本上尝试获取主线程来运行,因此它可以处理该信号,但由于它不直接控制哪个线程运行(这是留给操作系统)它基本上告诉操作系统,以保持线程切换,直到其最终主线程(如果你运气不好可能需要一段时间它)。

有帮助吗?

解决方案

我从来没有听说过使用taskset的用于与Python性能增益任何人。但这并不意味着它不能在你的情况发生,但绝对发布你的结果,以便其他人可以批评你的基准测试方法,并提供验证。

个人虽然,我将从使用消息队列中的CPU结合的螺纹解耦I / O线程。这样,你的前端现在已经完全网络I / O限制(一些与HTTP接口,一些与消息队列接口),非常适合您的线程的情况。然后,CPU激烈进程既可以使用多处理或仅仅是单个进程等待工作来对消息到达队列。

在长远来看您可能还需要考虑与扭曲或类似的 eventlets 的,因为即使他们不会帮助性能应提高可伸缩性。后端是现在已经可伸缩的,因为你可以在任意数量的机器需要+ CPU上运行的消息队列。

其他提示

另一种解决方案是: http://docs.python.org/library/multiprocessing.html

注1:这是的 Python语言的限制,但CPython的实施

注2:关于亲和力,你的操作系统应该不会有问题这样做本身

这是有趣的解决方案是由莱恩·凯利在他的博客报道的实验:的 http://www.rfk.id.au/blog/entry/a-gil-adventure-threading2/

结果似乎很理想。

我已经找到了足够的经验,多年来以下规则:如果工人都依赖于一些共享的状态,我用每核心(CPU绑定)一个多进程,每个核心的工作线程池修复(我/ O绑定)。操作系统将采取assigining不同的Python工艺在芯照顾。

Python的GIL是每Python解释。这意味着唯一以避免同时做多被简单地启动多个解释器(即,使用单独的过程,而不是线程并发),然后使用一些其它IPC原语的进程(如插座)之间的通信与它的问题。如此说来,该GIL是不使用与阻塞I / O调用线程时的一个问题。

如前面提到的GIL的主要问题是,你不能在同一时间执行2级不同的Python代码的线程。线程阻塞上的阻塞I / O呼叫被封锁,因而不executin Python代码。这意味着它没有阻止GIL。如果你有单独的线程蟒两颗CPU密集型任务,这也正是GIL在Python杀多处理(仅CPython的实现,如前面所指出的)。因为GIL停止CPU#1从执行线程蟒而CPU#0是忙于执行其他蟒线程。

在此之前作为GIL从Python中除去,协同例程来代替线程使用。我有充分根据,这一策略已被两次成功的创业实现,使用greenlets在至少一种情况。

这是一个很老的问题,但因为每次我搜索一下有关Python和性能的多核系统的信息这个职位一直是结果名单上,我不会让这个过去之前我一个不同意我的想法。

您可以使用多模块,而不是为每个任务创建线程,它创建的CPython compier解释你的代码的另一种方法。 它将使您的应用程序可以充分利用多核系统的优势。 我对这种方法看到的唯一的问题是,你将通过创建内存一个全新的进程堆栈有一个相当大的开销。 ( http://en.wikipedia.org/wiki/Thread_(computing)#How_threads_differ_from_processes

的Python多处理模块: http://docs.python.org/dev/library/multiprocessing.html

“我不使用多处理模块的原因是(在这种情况下)中的程序的一部分,在很大程度上网络I / O绑定(HTTP请求),所以具有工作线程池是一个伟大的方式压榨性能了一个盒子的......“

关于这一点,我想,你也可以有过程的池太:的 http://docs.python.org/dev/library/multiprocessing.html#using-a-pool-of-workers

ATT, 利奥

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top