multiprocessing
我想从这个例子开始尝试不同的使用方式:
$ cat multi_bad.py
import multiprocessing as mp
from time import sleep
from random import randint
def f(l, t):
# sleep(30)
return sum(x < t for x in l)
if __name__ == '__main__':
l = [randint(1, 1000) for _ in range(25000)]
t = [randint(1, 1000) for _ in range(4)]
# sleep(15)
pool = mp.Pool(processes=4)
result = pool.starmap_async(f, [(l, x) for x in t])
print(result.get())
这l
是一个列表,当产生 4 个进程时,该列表被复制 4 次。为避免这种情况,文档页面提供了使用队列、共享数组或使用multiprocessing.Manager
. 对于最后一个,我更改了以下定义l
:
$ diff multi_bad.py multi_good.py
10c10,11
< l = [randint(1, 1000) for _ in range(25000)]
---
> man = mp.Manager()
> l = man.list([randint(1, 1000) for _ in range(25000)])
结果看起来仍然正确,但是执行时间急剧增加,以至于我认为我做错了什么:
$ time python multi_bad.py
[17867, 11103, 2021, 17918]
real 0m0.247s
user 0m0.183s
sys 0m0.010s
$ time python multi_good.py
[3609, 20277, 7799, 24262]
real 0m15.108s
user 0m28.092s
sys 0m6.320s
文档确实说这种方式比共享数组慢,但这感觉不对。我也不确定如何对此进行分析以获取有关正在发生的事情的更多信息。我错过了什么吗?
PS 使用共享阵列,我得到的时间低于 0.25 秒。
PPS 这是在 Linux 和 Python 3.3 上。