2012-03-25 30 views
3

使用下面我得到奇怪的輸出代碼:試圖瞭解多處理主要在python

import sys 
from multiprocessing import Process 
import time 
from time import strftime 

now =time.time()  
print time.strftime("%Y%m%d %H:%M:%S", time.localtime(now)) 

fr= [1,2,3] 
for row in fr: 
    print 3 

print 1 

def worker(): 
    print 'worker line' 
    time.sleep(1) 
    sys.exit(1) 

def main(): 
    print 'start worker' 
    Process(target=worker, args=()).start() 
    print 'main line' 

if __name__ == "__main__": 
    start_time = time.time() 
    main() 
    end_time = time.time() 
    duration = end_time - start_time 
    print "Duration: %s" % duration 

輸出是:

20120324 20:35:53 
3 
3 
3 
1 
start worker 
main line 
Duration: 0.0 
20120324 20:35:53 
3 
3 
3 
1 
worker line 

我想我會得到這樣的:

20120324 20:35:53 
3 
3 
3 
1 
start worker 
worker line 
main line 
Duration: 1.0 

這是爲什麼運行兩次?在WinX64使用Python 2.7:

20120324 20:35:53 
3 
3 
3 
1 
worker line 

回答

0

這是我所得到的,當我運行使用Python 2.7.3上的Linux代碼:

20120324 23:05:49 
3 
3 
3 
1 
start worker 
main line 
Duration: 0.0045280456543 
worker line 

我不知道爲什麼你運行兩次,但我可以告訴你爲什麼它不會返回預期的持續時間或以「正確」的順序打印。

當您使用multiprocessing啓動進程時,啓動是異步的。也就是說,.start()函數會立即在父進程中返回,以便父進程可以繼續工作並執行其他操作(如啓動更多進程),而子進程在後臺自行執行。如果您想阻止父進程繼續進行,直到子進程結束,則應使用.join()函數。像這樣:

def main(): 
    print 'start worker' 
    p = Process(target=worker, args=()) 
    p.start() 
    p.join() 
    print 'main line' 
5

問題基本上是因爲multiprocessing真的設計爲POSIX系統,一個與fork(2)系統調用運行。在這些操作系統上,該進程可以分爲兩部分,孩子從父母中奇蹟般地克隆狀態,並且兩者都恢復在同一地點運行,現在孩子擁有新的進程ID。在這種情況下,multiprocessing可以安排一些機制,根據需要將狀態從父母發送到孩子,孩子確實已經擁有大部分所需的蟒蛇狀態。

Windows沒有fork()

multiprocessing必須撿起鬆弛。這基本上涉及啓動運行多處理子腳本的全新python解釋器。幾乎立即,父母會要求孩子使用父母狀態中的某些東西,因此孩子將不得不重新從頭創建該狀態,通過將您的腳本導入孩子

因此,在腳本中導入時發生的任何事情都會發生兩次,一次發生在父代中,另一次發生在子代中,因爲它會重新創建爲父代服務所需的python環境。

+0

但爲什麼似乎腳本運行兩次vs只有工人運行兩次?而不是打印1,如果我已經調用了模塊或其他腳本,該模塊/腳本是否也會運行兩次....我將如何控制啓動的進程數量。 – Merlin 2012-03-25 15:39:25

+0

工作人員不是兩次運行,而是工作人員運行一次,「父」運行一次。所有的頂級代碼都是在執行'python myscript.py'時執行的,但是當腳本調用'multiprocessing.Process()',它執行'python -m multiprocessing.child'時,它會重新運行,轉而做一個'import myscript'。 – SingleNegationElimination 2012-03-25 15:49:54