cpu_count
In [1]: from multiprocessing import cpu_count
In [2]: print(cpu_count())
56
Pickle
将任务分发到多个进程时,进程之间不共享内存,需要序列化object来传递消息(使用pickle)
Process
所有进程都放在内存中,FIFO (先进先出) 执行。若有挂起则安排新进程执行。
Pool
Pool
是我最常用的工具之一,用于构建进程池并发执行多个计算任务。使用时要尽量使任务均匀,每个任务耗费的资源差不多。Pool
使用FIFO将任务分配到处理器,有点像map-reduce。将输入映射到不同的处理器上,然后收集输出。所有任务执行完毕后,返回list或者array。执行中的进程在内存中,其余不在内存中。
p = mp.Pool(num_workers)
p.map(func, args, chunksize)
这里的func必须是可被pickle的object, chunksize是每次分发到每个worker的任务数量,chunksize越大,memory消耗越多, 但是如果iterable很大的话,chunksize大有助于加速。map会阻塞当前进程直到函数运行完成。
除了map之外,也可以使用apply
和apply_async
。Pool.apply
有点像python的apply,只是是在另外一个进程中调用。 apply会阻塞直到函数运行结束。apply_async则马上返回结果--一个AsyncResult对象,使用get可以提取函数运行结果。get会阻塞直到函数运行完成。
map是保序的,apply_async则不行。
Multiprocessing的问题
- 无法处理静态方法,类内方法,匿名函数,难以pickle
- 函数参数
pathos.multiprocessing
用dill替代了pickle,可以缓存一些pickle无法序列话的object, 详见pathos