我正在尝试以下代码:
from multiprocessing import Pool
def f(x):
return x
if __name__ == '__main__':
p = Pool(5)
print(p.map(f, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13]))
据我所知,5个处理器获得0, 1, 2, 3, 4
来执行操作。如果处理器1完成了它的工作,它会立即得到5
,而其余的处理器忙于1,2,3,4
或者所有处理器的代码都完成,以便下一批将一起得到{{ 1}}等等。如果后来发生了如何实现上面的代码,那么当处理器进入空闲状态时,它会分配给它的新工作?
如何测试实施?
答案 0 :(得分:2)
Threadpool会立即生成一个新线程(添加到您的示例中)。注意线程4如何花费足够长的时间才能启动第12个任务。
PS我刚注意到你忘记了10。
from multiprocessing import Pool
import time
import random
def f(x):
print "Enter %s" % x
time.sleep( random.randrange(1,100,1)/10.0 )
print "Exit %s" % x
return x
if __name__ == '__main__':
p = Pool(5)
print(p.map(f, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13]))
Enter 0
Enter 1
Enter 2
Enter 3
Enter 4
Exit 0
Enter 5
Exit 3
Enter 6
Exit 2
Enter 7
Exit 5
Enter 8
Exit 1
Enter 9
Exit 6
Enter 11
Exit 11
Enter 12
Exit 4
Enter 13
Exit 7
Exit 12
Exit 9
Exit 8
Exit 13
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13]
答案 1 :(得分:1)
是的,这种情况是可能的。首先将输入分区为单独的任务。当任务的大小不均匀(就处理时间而言)时,问题就出现了,并且它们太少而无法填补空白。
地图( func ,可迭代 [, chunksize ])
此方法将iterable切割为多个块,并将其作为单独的任务提交给进程池。 (近似)大小 可以通过将chunksize设置为正数来指定这些块 整数。
为了说明这种行为,我更改了f(x)
,因此需要x
秒才能完成。
from multiprocessing import Pool
import time
import threading
def f(x):
print('x: ' + str(x) + '\tThread ID: ' + str(threading.get_ident()))
time.sleep(x)
if __name__ == '__main__':
chunksize = 3
with Pool(2) as p:
p.map(f, [10, 1, 1, 1, 1, 1], chunksize)
输入数组[10, 1, 1, 1, 1, 1]
被划分为len(arr) / chunksize = 2
个组:
[10, 1, 1] # For thread 1, takes 12 seconds to finish
[ 1, 1, 1] # For thread 2, takes 3 seconds to finish
因此,线程2将在3秒后完成,而线程1将继续工作9秒钟。
示例输出:
x: 10 Thread ID: 8556
x: 1 Thread ID: 59180
x: 1 Thread ID: 59180
x: 1 Thread ID: 59180
x: 1 Thread ID: 8556
x: 1 Thread ID: 8556
如果您发现自己处于这种情况,那么您可以强制使用较小的chunksize
。值1确保尽可能平衡工作负载,但代价是更高的开销。