2016-08-23 26 views
0

我試圖從不同的線程訪問全局字典。一個完整的例子如下:從Python線程/進程更新全局對象

results = {0: 'pass'} 

def checkResult(thread_num, result_map): 
    while(True): 
     results[thread_num] = 'fail' 
     print('Thread results : '+str(results)) 
     time.sleep(5) 

multiprocessing.Process(target = checkResult, args=(1, results)).start() 
multiprocessing.Process(target = checkResult, args=(2, results)).start() 

while(True): 
    print('Main results: '+str(results)) 
    time.sleep(3) 

的「主要成果」只看到線程0,而「線程結果」只修改字典按自己的線程的結果:

Thread results : {0: 'pass', 1: 'fail'} 
Main results: {0: 'pass'} 
Thread results : {0: 'pass', 2: 'fail'} 
Main results: {0: 'pass'} 
Thread results : {0: 'pass', 1: 'fail'} 
Thread results : {0: 'pass', 2: 'fail'} 
Main results: {0: 'pass'} 
^C 

看來, 「結果」映射是按值傳遞的,而不是通過引用傳遞。有沒有辦法讓線程引用原始全局映射,而不是讓每個線程都使用它自己的副本?

我知道我應該使用鎖定來避免一個線程覆蓋另一個線程的更改(並且我計劃在實際解決方案中這樣做)的問題。現在,儘管我只是想讓所有線程都使用通用的結果字典。

+0

您正在使用多個進程,而不是線程。 – syntonym

+0

檢查[這](http://stackoverflow.com/questions/10797998/is-it-possible-to-multiprocess-a-function-that-returns-something-in-python)答案,它解釋瞭如何傳遞結果從子進程返回。 – FujiApple

回答

1

您需要的是並行訪問全局對象,這可以通過使用線程而不是進程完成。所有線程共享相同的地址空間,這意味着他們可以訪問相同的引用。 (而不是使用帶整數鍵的字典,你可以使用列表)

如果你使用的是獨特的「線程號」,你實際上不需要擔心競爭條件,因爲每個線程寫入它是自己的索引。

像這樣的東西應該做的伎倆:

import _thread, time 

results = {0 : 'pass'} 

def checkResult(thread_num): 
    while True: 
     results[thread_num] = 'fail' 
     print('Thread results: ' + str(results)) 
     time.sleep(3) 

_thread.start_new_thread(checkResult, (1,)) 
_thread.start_new_thread(checkResult, (2,)) 

while True: 
    print('Main results: ' + str(results)) 
    time.sleep(3) 

this可以幫助你)

+0

啊,那完美!我甚至沒有意識到線程和多處理之間的區別,但它是有道理的。 (和「線程號碼」的東西是我的簡化超越識別範例的一部分,但謝謝你的提示!) –