【发布时间】:2018-02-13 05:13:03
【问题描述】:
multiprocessing 模块中的ThreadPool 和Pool 有什么区别。当我尝试我的代码时,这是我看到的主要区别:
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]
使用“线程池”:
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 的官方文档,有人可以帮我看看在哪里可以找到它吗?
【问题讨论】:
-
据我所知,由于Python中的GIL,Python的多线程看起来像多线程,但不是真的。如果你想通过 python 来利用你的多核,你需要使用多处理。在现代计算机中,创建进程和创建线程的成本几乎相同。
-
创建线程的成本可能与创建进程的成本相似,但线程之间的通信与进程之间的通信成本却大不相同(除非您使用共享内存)。此外,您对 GIL 的评论只是部分正确:它是在 I/O 操作期间发布的,甚至在 CPU 绑定操作期间也由某些库(例如 numpy)发布。尽管如此,GIL 最终还是在 Python 中使用单独进程的原因。
-
@Yves 通过使用
fork,在 *nix 上可能是这样,但在 Windows 上却不是这样,并且没有考虑到进程之间通信的额外开销、限制和复杂性,因为与线程相反(在所有平台上)。 -
要回答
threading与ThreadPool的问题,threading没有简单的直接方法来获取工作函数的返回值。而在ThreadPool中,您可以轻松获取工作函数的返回值。
标签: python python-3.x multiprocessing threadpool python-multiprocessing