小编典典

多处理模块中的ThreadPool与Pool之间有什么区别?

python

请告诉我之间的差异ThreadPool,并Poolmultiprocessing模块。当我尝试代码时,这是我看到的主要区别:

from multiprocessing import Pool
import os, time

print("hi outside of main()")

def hello(x):
    print("inside hello()")
    print("Proccess id: ", os.getpid())
    time.sleep(3)
    return x*x

if __name__ == "__main__":
    p = Pool(5)
    pool_output = p.map(hello, range(3))

    print(pool_output)

我看到以下输出:

hi outside of main()
hi outside of main()
hi outside of main()
hi outside of main()
hi outside of main()
hi outside of main()
inside hello()
Proccess id:  13268
inside hello()
Proccess id:  11104
inside hello()
Proccess id:  13064
[0, 1, 4]

使用“ ThreadPool”:

from multiprocessing.pool import ThreadPool
import os, time

print("hi outside of main()")

def hello(x):
    print("inside hello()")
    print("Proccess id: ", os.getpid())
    time.sleep(3)
    return x*x

if __name__ == "__main__":
    p = ThreadPool(5)
    pool_output = p.map(hello, range(3))

    print(pool_output)

我看到以下输出:

hi outside of main()
inside hello()
inside hello()
Proccess id:  15204
Proccess id:  15204
inside hello()
Proccess id:  15204
[0, 1, 4]

我的问题是:

  • 为何每次在__main __()外运行Pool

  • multiprocessing.pool.ThreadPool没有产生新的进程?它只是创建新线程?

  • 如果是这样,使用multiprocessing.pool.ThreadPool与仅使用threading模块之间有什么区别?

我在任何ThreadPool地方都没有看到任何官方文档,有人可以在哪里找到我吗?


阅读 155

收藏
2020-12-20

共1个答案

小编典典

multiprocessing.pool.ThreadPool行为一样multiprocessing.Pool,唯一的区别在于使用线程,而不是进程运行的工人逻辑。

你看到的原因

hi outside of main()

会被多次打印multiprocessing.Pool是由于该池将生成5个独立的进程。每个进程将初始化其自己的Python解释器并加载模块,从而导致print再次执行顶层。

请注意,仅当使用spawn进程创建方法时才会发生这种情况(Windows上仅此方法可用)。如果使用fork一个(Unix),则与线程一样,该消息仅打印一次。

multiprocessing.pool.ThreadPool作为其实现从未完成未记录。它缺少测试和文档。您可以在源代码中看到其实现。

我相信下一个自然的问题是:何时使用基于线程的池,何时使用基于进程的池?

经验法则是:

  • IO绑定作业-> multiprocessing.pool.ThreadPool
  • CPU绑定作业-> multiprocessing.Pool
  • 混合作业->取决于工作量,multiprocessing.Pool由于流程隔离带来的优势,我通常更喜欢

在Python
3上,您可能需要看一下concurrent.future.Executor池的实现。

2020-12-20