Multiprocessing.Pool
在询问如何在 Python 中使用线程时,简单的答案是:“不要。使用进程,而不是。” 多处理模块允许你创建具有与创建线程类似的语法的进程,但我更喜欢使用它们方便的 Pool 对象。
使用 David Beazley 首先用于显示线程对 GIL 的危险的代码 ,我们将使用 multiprocessing.Pool重写它 :
David Beazley 的代码显示了 GIL 线程问题
from threading import Thread
import time
def countdown(n):
while n > 0:
n -= 1
COUNT = 10000000
t1 = Thread(target=countdown,args=(COUNT/2,))
t2 = Thread(target=countdown,args=(COUNT/2,))
start = time.time()
t1.start();t2.start()
t1.join();t2.join()
end = time.time()
print end-start
使用 multiprocessing.Pool 重写:
import multiprocessing
import time
def countdown(n):
while n > 0:
n -= 1
COUNT = 10000000
start = time.time()
with multiprocessing.Pool as pool:
pool.map(countdown, [COUNT/2, COUNT/2])
pool.close()
pool.join()
end = time.time()
print(end-start)
这不会创建线程,而是创建新流程。由于每个进程都是自己的解释器,因此没有 GIL 冲突。multiprocessing.Pool 将打开与机器上的核心一样多的进程,但在上面的示例中,它只需要两个。在实际场景中,你希望将列表设计为至少与计算机上的处理器一样长。池将运行你告诉它与每个参数一起运行的函数,直到它创建的进程数。函数完成后,列表中的任何剩余函数都将在该进程上运行。
我发现,即使使用 with
语句,如果不关闭并加入池,进程仍然存在。为了清理资源,我总是关闭并加入我的池。