Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python线程都在单个内核上执行_Python_Multithreading_Performance - Fatal编程技术网

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

Python线程都在单个内核上执行,python,multithreading,performance,Python,Multithreading,Performance,我有一个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。很

我有一个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。很明显,我不能强迫操作系统做任何事情,但我以前从未注意过像这样的多线程代码的性能,所以我想知道我是否只是遗漏了什么或误解了什么


谢谢。

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

如需解决此问题的方法,请尝试以下建议:


AFAIK,在CPython中,全局解释器锁意味着在任何时候运行的Python代码不能超过一个块。尽管这实际上不会影响单处理器/单核机器中的任何东西,但在多核机器上,这意味着在任何时候都只有一个线程在运行,这会导致所有其他内核都处于空闲状态。

请注意,在许多情况下(实际上,在所有情况下,“昂贵的操作”都是用Python实现的计算),多个线程实际上不会同时运行,因为Python的

GIL是一个解释器级锁。 此锁阻止执行 Python中一次有多个线程 口译译员每一条想要 跑步时必须等待GIL恢复 由另一个线程释放,该线程 表示您的多线程Python 应用程序基本上是单一的 螺纹的,对吗?对不完全是。 有点

CPython使用所谓的“操作系统” 盖下的“系统”螺纹, 也就是说每次请求 制造一条新的线,则 解释器实际上调用 操作系统的库和 内核生成一个新线程。这 例如,与Java相同。所以 在内存中,您确实有多个 螺纹和正常工作状态 系统控制哪个线程正在运行 计划运行。在倍数表上 处理器机器,这意味着你 可能有许多线程分布在 多处理器,都很开心 干劲十足地干活儿

然而,虽然CPython使用 操作系统线程(理论上) 允许多线程执行 口译员内部 同时,口译员也 强制GIL由一个 线程,然后才能访问 解释器和堆栈,并可以修改 所有内存中的Python对象 毫不犹豫地。后一点是原因 GIL存在:GIL阻止 同时访问Python对象 通过多个线程。但事实并非如此 拯救你(如银行所示) 示例)从锁敏感 生物;你不能搭便车。 GIL在那里是为了保护环境 翻译记忆,而不是你的理智

有关详细信息,请参阅的“全局解释器锁”部分

要解决此问题,请查看

多个流程(明智使用) 是[…]一个更好的 为多CPU编写应用程序的方法 盒子比线多


--

非常感谢您的详细回答-
多处理
是吗。对于其他感兴趣的人,
multiprocessing.Pool
还解决了限制活动工作线程数量的问题。那么我在Windows上该怎么办?多进程在Windows上很糟糕,因为子进程不从父进程的内存继承对象。我想把一个函数的多线程映射到一个大的列表上。答案很好。但我仍然不清楚多线程。假设我的计算机有4个内核,我用python代码创建了4个线程。据我所知,由于GIL,这些线程将只在1个(物理)内核中生成,对吗?在其他语言中,这些线程可以在不同的内核中生成?我不确定如何在物理内核中分配线程。线程是严格在同一个内核中创建的,还是依赖于其他东西(例如,操作系统、编程语言等)。谢谢。@Catbuilts Python不指定在哪些物理内核上创建线程,这是由操作系统控制的。GIL所做的是限制线程在Python层所做的工作:一次只允许一个线程修改Python解释器的状态,因此任何试图这样做的额外线程都将处于空闲状态,直到轮到它们操作为止。多个进程不会受到GIL的影响,因为每个进程都有自己的GIL和内存。@Sven:谢谢你提供的信息。我想知道,在其他不使用GIL的编程语言中,线程可以在多进程上运行吗?例如,在4核计算机上创建一个具有4个线程的程序,这些线程是否在所有4核上执行?python中的所有线程都是在1个内核上生成的,这是因为GIL吗?