【问题标题】:multiprocessing and multithreading in python 3python 3中的多处理和多线程
【发布时间】:2020-03-23 21:39:33
【问题描述】:

我知道 python 中有一个 GIL 强制线程仅在 1 个核心上执行。但是我根据处理器内核的数量创建了进程,并且在每个进程中我都创建了线程。理论上,它们会在每个进程中并行执行吗?如果它有效,我如何在使用 Pool 时同步所有内容

from multiprocessing import Pool
from concurrent.futures import ThreadPoolExecutor

def make_threads(data):
 with ThreadPoolExecutor(len(data)) as executor:
     answer=list(executor.map(some_function,data))
     return answer

def main():
with Pool(processes_count) as p:
         answer=list(p.map(make_threads,data))```

【问题讨论】:

  • 每个工作进程中的线程仍然是 GIL 绑定的,所以如果工作都是 CPU 绑定的,跳过线程,直接使用进程池。
  • 我遇到了一个问题,我不能使用超过62个进程,并且线程没有这样的限制。每个工作流中的线程仍然会绑定到 GIL,但是不同进程中的线程会并行工作吗?如果是这样,那么这比仅仅一个线程池要好。
  • 除非线程正在做 IO 绑定的事情,否则每个进程只有一个线程可以做任何事情。因此,很少有充分的理由将两者混为一谈。只需为每个 CPU 内核生成一个进程,然后将所有工作发送给它们(池类型旨在为您拆分)。
  • 如果您正在使用像 numpy/pandas/scikit 这样释放 GIL 进行计算的工具,那么线程将并行运行。
  • 您的系统有多少个处理器?如果您是 cpu 密集型的,那么更多的进程往往会因更多的调度和更多的内存使用而减慢速度。将您的进程池限制为内核数(甚至更少,因为其他进程正在运行)并让map 进行调度。

标签: python multithreading multiprocessing gil


【解决方案1】:

如果可以,请使用 concurrent.futures 而不是多处理或多线程 - 这是一个更好的 API,可让您方便地从线程切换到进程,反之亦然。

在给定的 python 进程中,线程可以很好地执行 I/O 绑定任务,但 CPU 绑定任务很差。如果你在单个进程中有 20 个 I/O 绑定线程和 1 个 CPU 绑定线程,那么它们都会出现性能问题 - CPU 绑定线程会弄乱 I/O 绑定线程。

通常队列是跨进程和线程进行通信的最佳方式。

【讨论】:

  • ProcessPoolExecutor使用concurrent.futures,脚本执行,但最后出现错误:OSError: handle is closed。我在论坛中没有找到答案,并决定使用 multiprocessing.Threads 与 selenium 一起工作。每个线程打开一个 webdriver,发送一个 get 请求,然后关闭 webdriver。就是这样。我不知道哪个在性能方面更好。
猜你喜欢
  • 1970-01-01
  • 2021-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多