問題描述
我有一個(gè) python 程序,它運(yùn)行蒙特卡羅模擬來尋找概率問題的答案.我正在使用多處理,這里是偽代碼
I have a python program that runs a Monte Carlo simulation to find answers to probability questions. I am using multiprocessing and here it is in pseudo code
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
我想對(duì)此進(jìn)行擴(kuò)展,以便統(tǒng)一計(jì)算已運(yùn)行的迭代次數(shù).就像如果線程 1 已經(jīng)運(yùn)行了 100 次,線程 2 已經(jīng)運(yùn)行了 100 次,那么我想總共顯示 200 次迭代,作為控制臺(tái)的打印.我指的是線程進(jìn)程中的 iterations
變量.如何確保所有線程都添加到同一個(gè)變量?我認(rèn)為使用 iterations
的 Global
版本會(huì)起作用,但事實(shí)并非如此.
I'd like to extend this so that I can keep a unified count of the number of iterations that have been run. Like if thread 1 has run 100 times and thread 2 has run 100 times then I want to show 200 iterations total, as a print to the console. I am referring to the iterations
variable in the thread process. How can I make sure that ALL threads are adding to the same variable? I thought that using a Global
version of iterations
would work but it does not.
推薦答案
正常的全局變量在進(jìn)程之間的共享方式與線程之間的共享方式不同.您需要使用流程感知數(shù)據(jù)結(jié)構(gòu).對(duì)于您的用例,multiprocessing.Value
應(yīng)該可以正常工作:
Normal global variables are not shared between processes the way they are shared between threads. You need to use a process-aware data structure. For your use-case, a multiprocessing.Value
should work fine:
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))
幾點(diǎn)說明:
- 我明確地將
Value
傳遞給孩子,以保持代碼與 Windows 兼容,Windows 無法在父子之間共享讀/寫全局變量. - 我用鎖保護(hù)了增量,因?yàn)樗皇窃硬僮鳎⑶胰菀资艿礁?jìng)爭(zhēng)條件的影響.
- 我添加了一個(gè)
if __name__ == "__main__":
保護(hù),再次幫助提高 Windows 兼容性,并作為一般最佳實(shí)踐.
- I explicitly passed the
Value
to the children, to keep the code compatible with Windows, which can't share read/write global variables between parent and children. - I protected the increment with a lock, because its not an atomic operation, and is susceptible to race conditions.
- I added an
if __name__ == "__main__":
guard, again to help with Windows compatibility, and just as a general best practice.
這篇關(guān)于在多處理期間保持統(tǒng)一計(jì)數(shù)?的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!