Python 线程都在一个内核上执行

我有一个生成许多线程的 Python 程序,它一次运行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

但是当程序运行时,OSX 中的活动监视器显示4个逻辑核心中的1个处于100% ,其他的几乎为0。显然,我不能强迫操作系统做任何事情,但是我从来没有像这样关注过多线程代码的性能,所以我想知道我是否遗漏了什么或者误解了什么。

谢谢。

60609 次浏览

Python 有一个 GIL,可以防止解释代码的线程被并发处理。

Http://en.wikipedia.org/wiki/global_interpreter_lock

Http://wiki.python.org/moin/globalinterpreterlock

要想避开这个问题,可以试试 多处理模块多处理模块,如下所示:

运行单独的 python 进程是否可以避免 GIL?

AFAIK,在 CPython 中,这个 GIL 意味着任何时候都不能运行多于一个 Python 代码块。虽然这对单处理器/单核机器没有实际影响,但在多核机器上,这意味着在任何时候实际上只有一个线程在运行——导致所有其他核都处于空闲状态。

请注意,在许多情况下(实际上在所有“昂贵的操作”是用 Python 实现的计算的情况下) ,由于 Python 的 GIL (GIL),多个线程实际上不会并发运行。

GIL 是解释器级别的锁。 此锁防止执行 在 Python 中同时使用多个线程 每个线程想要 运行必须等待 GIL 由另一个线程释放,其中 意味着你的多线程 Python 应用基本上是单一的 - 螺纹,对吧?-是的,不完全是。 算是吧。

CPython 使用所谓的“操作” 盖子下的螺纹, 也就是说,每次请求 制作一个新的线程,该 解释器实际上调用 操作系统的库和 内核来生成一个新线程 例如,它和 Java 是一样的。所以 在内存中你确实有很多 螺纹和通常的操作 系统控制哪个线程是 计划运行。在一个多 处理器机器,这意味着你 可能有许多线散布在各处 多个处理器,一切都很顺利 埋头苦干。

然而,当 CPython 使用 操作系统线程(理论上) 允许多个线程执行 在翻译中 同时) ,译员也 迫使 GIL 被一个 线程访问 解释器和堆栈,并可以修改 内存中的 Python 对象 不管你愿不愿意,后一点就是原因 GIL 存在: GIL 防止 同时访问 Python 对象 通过多个线程。但这不是 拯救你(如银行所示) 例子)作为一个锁敏感 你不会得到免费的交通工具。 GIL 是为了保护 解读记忆,而不是你的理智。

有关详情,请参阅 ABc0的 GIL 部分。

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

多重程序(明智地使用) 是[ ... ]一个更好的 为多 CPU 编写应用程序的方法 盒子而不是线。

—— 吉多·范罗苏姆(Python 的创造者)