我想知道启动工作池以并行管理任务或者在挑选和分配工作时启动单个流程有什么区别。
我确实有一个任务(此处do_my_job
),其对象无法被腌制。因此,我无法启动一个工作池来并行执行任务。以下代码段不起作用,其中iterator
遍历do_my_job
的不同参数设置:
import multiprocessing as multip
mpool = multip.Pool(ncores)
mpool.map(do_my_job, iterator)
mpool.close()
mpool.join()
然而,以下代码片段可以工作:
import time
import multiprocessing as multip
keep_running=True
process_list = []
while len(process_list)>0 or keep_running:
terminated_procs = []
for idx, proc in enumerate(process_list):
if not proc.is_alive():
terminated_procs.append(idx)
for terminated_proc in terminated_procs:
process_list.pop(terminated_proc)
if len(process_list) < ncores and keep_running:
try:
task = iterator.next()
proc = multip.Process(target=do_my_job,
args=(task,))
proc.start()
process_list.append(proc)
except StopIteration:
keep_running=False
time.sleep(0.1)
我在后一种情况下的工作如何分配给各个流程?在进程启动之前,是否没有步骤来挑选任务和涉及的所有相关对象?如果不是如何将任务和对象传递给新进程?
答案 0 :(得分:4)
当您fork
新进程时,子进程将继承其父数据。因此,如果父级在分叉之前定义变量,则子级将能够看到它,因为它是它自己的变量。在fork
系统调用子进程和父进程之后,应使用某些IPC在它们之间共享数据。
当您创建Pool
时,您正在分配N个进程,然后,当您致电map
时,您会将数据传递给他们。但是,因为这些进程已经分叉,所以共享这些数据的唯一方法是使用IPC,它涉及“挑选”对象。在后一种情况下,您在创建数据之后分支,因此子进程能够像它自己一样访问它。
我认为你能做的最好的事情就是让你的对象“可选”。