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

时间:2017-09-05 01:52:53

标签: python python-3.x multiprocessing threadpool 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)

我看到以下输出:

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]

我的问题是:

  • 为什么每次都在Pool中运行“外部__main __()”?

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

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

我在任何地方都看不到ThreadPool的任何官方文档,有人可以帮助我找到它的位置吗?

1 个答案:

答案 0 :(得分:50)

multiprocessing.pool.ThreadPoolmultiprocessing.Pool的行为相同,唯一的区别是使用线程而不是进程来运行工作逻辑。

你看到的原因

hi outside of main()

使用multiprocessing.Pool多次打印是因为池将spawn 5个独立进程。每个进程都将初始化自己的Python解释器并加载模块,从而导致再次执行顶级print

请注意,仅当使用spawn进程创建方法时才会发生这种情况(仅限Windows上可用的方法)。如果您使用fork(Unix),您将看到仅为线程打印一次消息。

multiprocessing.pool.ThreadPool未记录,因为其实施从未完成。它缺乏测试和文档。您可以在source code

中查看其实施情况

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

经验法则是:

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

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