2015-07-09 176 views
0

这是我运行的一段代码。我试图确保在继续完成我的代码之前完成所有流程,但这并不像我期望的那样发生。使用multiprocessing.join()不会阻止执行

import sys 
import multiprocessing as mp 
import time 
import random 

def testJoin(argin): 
    name = mp.current_process().name 
    exStartTime = time.time() 
    time.sleep(argin * random.random()) 
    print(name + ' took %d seconds' %(time.time() - exStartTime)) 
    sys.stdout.flush() 


if __name__ == '__main__': 
    instances = [10, 10, 10, 10] 
    jobs = [] 
    for k in instances: 
     p = mp.Process(target = testJoin, args = (k,)) 
     jobs.append(p) 
     p.start() 
    p.join() 

print('End of Program') 

这里是什么正在输出:

End of Program 
Process-4 took 1 seconds 
End of Program 
End of Program 
Process-2 took 4 seconds 
End of Program 
Process-1 took 9 seconds 
End of Program 
Process-3 took 9 seconds 

当我感到困惑的是,我不希望看到“计划结束”印刷不止一次,我当然不期望看到它的印刷,直到我所有的四个过程都结束。我错过了什么?

回答

0

你描述的行为在Unix下不会发生,但它在Windows下。 Windows缺少os.fork,所以为了启动一个子进程,multiprocessing starts a new Python interpreter and imports the calling module

if __name__ == "__main__"protects code from getting executed导入时。由于

print('End of Program') 

不是if-statement里面,它就会被每个通话模块是进口的,一旦由主处理时间执行一次。

解决方案是简单地把print调用内if-statement

+0

这是一个很好的解释。也就是说,我有可能是一个愚蠢的后续问题。这是否意味着,如果程序中有各个步骤依赖于对方,那么最终会嵌套if __name__ =='__main__'语句?没有更好的方法吗? – Marc

+0

通常一个程序的结构在脚本结尾附近只有一个'if __name__ =='__main __''。它甚至可以包含一个函数的调用,比如'main()'。 'if-statement'上面是导入模块的行,定义了全局常量和函数定义。我没有看到任何理由永远嵌套'if __name__ =='__main __''语句,因为if语句的内部条件永远都是真的...... – unutbu

+0

您可以考虑'main'语句函数作为由主进程执行的那些函数,而'testjoin'函数中的那些函数是由产生的子进程执行的函数。两者之间的任何交互都必须通过队列,或共享内存数据结构或进程间通信(IPC)的其他一些机制来完成。 – unutbu