python - ProcessPoolExecutor 和 ThreadPoolExecutor 有什么区别?

标签 python python-3.x multithreading parallel-processing python-3.5

我阅读文档试图获得基本的理解,但它只表明 ProcessPoolExecutor 允许回避 Global Interpreter Lock 我认为这是锁定的方式一个变量或函数,以便并行进程不会同时更新其值。

我正在寻找的是何时使用 ProcessPoolExecutor 以及何时使用 ThreadPoolExecutor 以及在使用每种方法时我应该记住什么!

最佳答案

ProcessPoolExecutor 在其单独的子进程中运行您的每个工作人员。

ThreadPoolExecutor 在主进程中的单独线程中运行您的每个 worker。

全局解释器锁 (GIL) 不只是锁定变量或函数;它锁定了整个解释器。这意味着每个内置操作,包括诸如 listodicts[3]['spam'] = eggs 之类的东西,都是自动线程安全的。

但这也意味着如果您的代码受 CPU 限制(也就是说,它把时间花在计算上而不是等待网络响应等),而不是将大部分时间花在旨在发布的外部库中GIL(如 NumPy),一次只有一个线程可以拥有 GIL。所以,如果你有 4 个线程,即使你有 4 个甚至 16 个内核,大多数时候,其中 3 个将等待 GIL。因此,您的代码并没有快 4 倍,而是变慢了一些。

同样,对于 I/O 绑定(bind)代码(例如,等待一堆服务器响应你发出的一堆 HTTP 请求),线程就很好;这仅适用于 CPU 绑定(bind)代码,这是一个问题。

每个单独的子进程都有自己单独的 GIL,因此这个问题就消失了——即使您的代码受 CPU 限制,使用 4 个子进程仍然可以使它的运行速度几乎提高 4 倍。

但是子进程不共享任何变量。通常,这是一件好事——您将值(的副本)作为参数传递给您的函数,然后返回值(的副本),并且进程隔离保证您可以安全地执行此操作。但偶尔(通常是出于性能原因,但有时也是因为您传递的对象无法通过 pickle 复制),这是 Not Acceptable ,因此您要么需要使用线程,要么使用multiprocessing 模块中更复杂的显式共享数据包装器。

关于python - ProcessPoolExecutor 和 ThreadPoolExecutor 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51828790/

相关文章:

c# - 如何在 C# 中解决车辆跟踪 GPS 收集数据的最佳解决方案?

python - 异步运行 Azure Durable Function

Python PyObjC_IdToPython(@protocol(NSURLSessionStreamDelegate)) 错误

python - 更新打印数据调试python

python - 如何从 Flask 提供 create-react-app 服务?

python-3.x - Keras 中的 model.evaluate() 未覆盖所有数据点

Python 创建一个空的稀疏矩阵

Ruby 多线程问题

java - 静态变量是否只为所有正在运行的线程占用一个内存位置?

python - SQL语句中并未使用所有参数使用python插入表