2015-04-28 55 views
1

我有一個python程序運行蒙特卡洛模擬來找到概率問題的答案。我用的多,在這裏它是僞代碼多處理期間保持統一計數?

import multiprocessing 

def runmycode(result_queue): 
    print "Requested..." 
    while 1==1: 
     iterations +=1 
    if "result found (for example)": 
     result_queue.put("result!") 

    print "Done" 

processs = [] 
result_queue = multiprocessing.Queue() 

for n in range(4): # start 4 processes 
    process = multiprocessing.Process(target=runmycode, args=[result_queue]) 
    process.start() 
    processs.append(process) 

print "Waiting for result..." 

result = result_queue.get() # wait 

for process in processs: # then kill them all off 
    process.terminate() 

print "Got result:", result 

我想延長,這樣我可以保持已運行的迭代次數統一計數。就像如果線程1已經運行100次並且線程2已經運行了100次那麼我想總共顯示200次迭代,作爲打印到控制檯。我指的是線程進程中的iterations變量。我怎樣才能確保所有線程都添加到相同的變量?我認爲使用iterationsGlobal版本可以工作,但事實並非如此。

回答

2

正常的全局變量不在進程之間共享它們在線程之間共享的方式。您需要使用流程識別數據結構。爲了您的用例,一個multiprocessing.Value應該很好地工作:

import multiprocessing 

def runmycode(result_queue, iterations): 
    print("Requested...") 
    while 1==1: # This is an infinite loop, so I assume you want something else here 
     with iterations.get_lock(): # Need a lock because incrementing isn't atomic 
      iterations.value += 1 
    if "result found (for example)": 
     result_queue.put("result!") 

    print("Done") 


if __name__ == "__main__": 
    processs = [] 
    result_queue = multiprocessing.Queue() 

    iterations = multiprocessing.Value('i', 0) 
    for n in range(4): # start 4 processes 
     process = multiprocessing.Process(target=runmycode, args=(result_queue, iterations)) 
     process.start() 
     processs.append(process) 

    print("Waiting for result...") 

    result = result_queue.get() # wait 

    for process in processs: # then kill them all off 
     process.terminate() 

    print("Got result: {}".format(result)) 
    print("Total iterations {}".format(iterations.value)) 

的幾個注意事項:

  1. 我明確地通過了Value給孩子,保持代碼與Windows兼容,哪些不能共享父/子之間的讀/寫全局變量。
  2. 我用鎖來保護增量,因爲它不是原子操作,並且容易受到競爭條件的影響。
  3. 我加了一個if __name__ == "__main__":後衛,再一次幫助Windows兼容性,就像一般的最佳實踐一樣。