2015-07-09 33 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