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

ozn*_*ozn 54 python multiprocessing threadpool python-3.x python-multiprocessing

请告诉我之间的差异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)
Run Code Online (Sandbox Code Playgroud)

我看到以下输出:

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]
Run Code Online (Sandbox Code Playgroud)

使用"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)
Run Code Online (Sandbox Code Playgroud)

我看到以下输出:

hi outside of main()
inside hello()
inside hello()
Proccess id:  15204
Proccess id:  15204
inside hello()
Proccess id:  15204
[0, 1, 4]
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  • 为什么"outside __main __()"每次都在运行Pool

  • multiprocessing.pool.ThreadPool不会产生新的流程?它只是创建新线程?

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

我没有看到任何ThreadPool地方的官方文档,有人可以帮助我找到它吗?

nox*_*fox 68

multiprocessing.pool.ThreadPool行为与相同multiprocessing.Pool与使用线程,而不是进程运行的工人逻辑的唯一区别.

你看到的原因

hi outside of main()
Run Code Online (Sandbox Code Playgroud)

被打印多次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池实现.

  • **为什么IO绑定作业-> multiprocessing.pool.ThreadPool? (4认同)
  • 使用 Process 而不是 Thread 的另一个原因是 mp 中涉及的库不是线程安全的。Pandas 就是这样一个著名的图书馆。如果您想使用 Pandas 同时执行多个大数据查询,那么 Process 可能是最安全的方法,因为进程之间不共享线程状态。 (3认同)
  • 关于未完成的ThreadPool实现的评论是否仍将在2019年使用Python 3.7生效? (2认同)
  • @MrR,这绝对合理且正确,但这实际上并没有解决**为什么** IO 绑定作业_应该_更喜欢 ThreadPool 而不是池(进程);不过,我认为这可以简单地通过常识来回答,即分叉整个子进程所需的时间以及由于无法共享相同资源而导致的额外开销。 (2认同)
  • 如果你可以在线程和CPU之间进行选择,考虑到同样的好处,你应该总是选择线程,因为,是的,开销更少。 (2认同)