我正在尝试在多处理中实现共享计数器。我使用一个全局变量来解决酸洗问题。由于我不理解的原因,增量似乎不适用于我的全局计数器列表(值总是0),我猜代码使用了被丢弃的变量的局部实例。
我认为全局列表可以被修改,因为它们是可变的。我还尝试显式定义global list_global
,以指定我想使用变量的全局定义。
from multiprocessing import Pool, Value, Lock
list_global = [] # global variable to hold Counter values
#http://eli.thegreenplace.net/2012/01/04/shared-counter-with-pythons-multiprocessing/
class Counter(object):
def __init__(self, initval=0):
self.val = Value('i', initval)
self.lock = Lock()
## self.val = initval
def increment(self):
with self.lock:
self.val.value += 1
def value(self):
with self.lock:
return self.val.value
def process_item(x):
global list_global
list_global[0].increment() # increments
return list_global[0].value() # correctly returns incremented value
def main():
global list_global
print 'before', list_global[0].value()
pool = Pool()
print pool.map(process_item, range(10))
pool.close()
pool.join()
#increments in process_item are not persistent
#(do not appear to be modifying the global variable)
print 'after', list_global[0].value() #=> 0
# list_global holds 3 Counter objects
for i in range(3):
list_global.append(Counter(0))
if __name__ == '__main__':
global list_global
main()
#print list_global # list_global holds "Counter" objects
for i in list_global:
print i.value(), #=>[0,0,0] # expected [10,0,0]
比我的评论更具体,您的问题是您从根本上误解了多处理正在做什么,这会对您的输出产生错误的期望。您不能声明一个全局变量,然后跨多个进程共享它。当您使用线程时,您可以避免更多的问题,但是为了理解为什么会遇到问题,您需要了解多处理在做什么。
当Pool.map()
启动子进程时,每个子进程都会启动自己的 python解释器,并在其中导入顶级函数process_item
。这个单独的解释器实例还创建了list_global
的自己的实例。对于每个子进程都会发生这种情况。对global
的调用并不只是神奇地使那些单独运行的进程共享在模块中定义的列表。