Python线程全部在单个内核上执行

我有一个Python程序,产生许multithreading,一次运行4,每个执行昂贵的操作。 伪代码:

for object in list: t = Thread(target=process, args=(object)) # if fewer than 4 threads are currently running, t.start(). Otherwise, add t to queue 

但是,当程序运行时,OS X中的活动监视器显示,4个逻辑内核中有1个处于100%,其他几乎是0.显然,我不能强制操作系统做任何事情,但我从来没有注意这样的multithreading代码的性能之前,所以我想知道如果我只是失踪或误解的东西。

谢谢。

请注意,在很多情况下(几乎所有的情况下,“昂贵的操作”是用Python实现的计算),由于Python的全局解释器锁(GIL) ,多个线程实际上不会同时运行。

GIL是一个解释者级的锁。 这个锁可以防止在Python解释器中一次执行多个线程。 每个想要运行的线程都必须等待其他线程释放GIL,这意味着你的multithreadingPython应用程序基本上是单线程的,对吗? 是。 不完全是。 有点。

CPython使用所谓的“操作系统”线程,也就是说每次创build一个新线程的请求,解释器实际调用操作系统的库和内核来生成一个新的线程。 例如,这与Java相同。 所以在内存中,你真的有多个线程,通常操作系统控制哪个线程计划运行。 在一个多处理器的机器上,这意味着你可以有多个线程分布在多个处理器上,所有的人都快乐地开始工作。

然而,尽pipeCPython确实使用了操作系统线程(理论上允许多个线程在解释器中同时执行),但是解释器也会强制GIL被线程获取,然后才能访问解释器和堆栈,并且可以修改内存中的Python对象所有这些都是愚蠢的。 后一点是GIL存在的原因:GIL阻止multithreading同时访问Python对象。 但是这并不能拯救你(如银行的例子所示)不是一个locking敏感的生物; 你没有搭便车。 GIL在那里保护口译员的记忆,而不是你的理智。

查看Jesse Noller的post的全球翻译locking部分了解更多详情。

为了解决这个问题,请查看Python的多处理模块 。

多个进程(审慎使用IPC)是一个更好的方法来编写比multithreading多CPU的应用程序。

– Guido van Rossum(Python的创build者)

Python有一个全局解释器锁,它可以防止解释代码的线程被同时处理。

http://en.wikipedia.org/wiki/Global_Interpreter_Lock

http://wiki.python.org/moin/GlobalInterpreterLock

有关如何解决这个问题,请尝试多处理模块 ,build议在这里:

是否运行单独的Python进程避免GIL?

AFAIK,在CPython中,全局解释器锁意味着一次只能运行一个以上的Python代码块。 虽然这不会影响单个处理器/单核机器中的任何内容,但在多核机器上,这意味着您一次只能有一个线程运行 – 导致所有其他内核空闲。