2013-12-20 25 views
3

我想知道启动一个工作池来并行管理一个任务或启动单个进程来执行酸洗和分配作业之间有什么区别。Python多处理,进程和池之间的区别,数据的酸洗

我有一个任务(这里是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) 

如何我在后一种情况下的工作分配给个别进程?在流程开始之前是否没有酸洗任务和涉及所有相关对象的步骤?如果不是如何将任务和对象传递给新进程?

回答

4

当你fork一个新的进程的子进程将继承他的父母的数据。因此,如果父母在分叉之前定义变量,则孩子将能够看到它,因为它是它自己的变量。在系统调用子进程和父进程之后,应该使用某个IPC在它们之间共享数据。 当您创建一个Pool时,您分叉了N个进程,然后当您拨打map时,您会将它们传递给他们。但是,因为这些过程已经分叉了,所以共享这些数据的唯一方法就是使用包含“酸洗”对象的IPC。在后一种情况下,您在之后创建,因此子进程能够访问它,因为它在自己的位置。 我认为你可以做的最好的事情就是让你的对象“可选”。

+0

复制了继承的数据,对吧?因此,无论子进程对数据做什么都不会修改父类的数据?! 不幸的是,我不能让我的对象“可选”,因为它的一部分来自第三方应用程序。 – SmCaterpillar

+1

通常它是“写入时复制”。孩子和父母会分享相同的“记忆”,直到他们中的一人尝试写作,然后复制。 – smeso

+0

@SmCaterpillar,您的主程序如何访问这些第三方对象?您可以在您的Pool进程中使用相同类型的代码来访问它们,可能是在进程初始化函数中。这里没有足够的细节来充实它。在极端情况下,您可以将代码作为*字符串*和'exec'传递给Pool进程中的字符串。总是有替代品;-) –