2016-08-23 27 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

啊,那完美!我甚至没有意识到线程和多处理之间的区别,但它是有道理的。 (和“线程号码”的东西是我的简化超越识别范例的一部分,但谢谢你的提示!) –