Python多处理 - 全局列表中的共享计数器没有正确递增

时间:2014-06-17 19:17:19

标签: python global-variables multiprocessing

我正在尝试在多处理中实现共享计数器。我正在使用全局变量来解决酸洗问题。由于我不明白的原因,增量似乎不适用于我的全局计数器列表(值始终为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]

1 个答案:

答案 0 :(得分:2)

比我的评论更具体,你的问题是你从根本上误解了多处理正在做什么,这会对你的输出产生错误的期望。您无法声明全局变量,然后跨多个进程共享它。当你使用Threads时,你可以稍微多一些,但为了理解你遇到麻烦的原因,你需要了解做什么

Pool.map()启动您的子进程时,每个进程都会启动自己的 python解释器,导入您的顶级函数process_item。这个单独的解释器实例还会创建自己的 list_global实例。对于每个子进程都会发生这种情况。您对global的来电不会神奇地使这些单独的正在运行的进程共享您模块中定义的列表。