python多处理中的共享变量

use*_*611 25 python multiprocessing

第一个问题是Value和Manager()之间有什么区别.值?

第二,是否可以在不使用Value的情况下共享整数变量?以下是我的示例代码.我想要的是获取一个值为整数的字典,而不是值.我所做的只是在整个过程之后改变它.有没有更简单的方法?

from multiprocessing import Process, Manager

def f(n):
    n.value += 1

if __name__ == '__main__':
    d = {}
    p = []

    for i in range(5):
        d[i] = Manager().Value('i',0)
        p.append(Process(target=f, args=(d[i],)))
        p[i].start()

    for q in p:
        q.join()

    for i in d:
        d[i] = d[i].value

    print d
Run Code Online (Sandbox Code Playgroud)

Chr*_*isP 34

使用时Value,ctypes在共享内存中获取一个对象,默认情况下使用该对象进行同步RLock.当您使用时,您将Manager获得一个SynManager控制服务器进程的对象,该对象允许其他进程操纵对象值.您可以使用同一个经理创建多个代理; 无需在循环中创建新的管理器:

manager = Manager()
for i in range(5):
    new_value = manager.Value('i', 0)
Run Code Online (Sandbox Code Playgroud)

Manager可以在计算机之间共享,但Value仅限于一台计算机. Value会更快(运行下面的代码看),所以我认为你应该使用它,除非你需要支持任意对象或通过网络访问它们.

import time
from multiprocessing import Process, Manager, Value

def foo(data, name=''):
    print type(data), data.value, name
    data.value += 1

if __name__ == "__main__":
    manager = Manager()
    x = manager.Value('i', 0)
    y = Value('i', 0)

    for i in range(5):
        Process(target=foo, args=(x, 'x')).start()
        Process(target=foo, args=(y, 'y')).start()

    print 'Before waiting: '
    print 'x = {0}'.format(x.value)
    print 'y = {0}'.format(y.value)

    time.sleep(5.0)
    print 'After waiting: '
    print 'x = {0}'.format(x.value)
    print 'y = {0}'.format(y.value)
Run Code Online (Sandbox Code Playgroud)

总结一下:

  1. 使用Manager创建多个共享对象,包括字典和列表.用于Manager在网络上的计算机之间共享数据.
  2. 使用ValueArray当不需要通过网络共享信息时,类型ctypes就足以满足您的需求.
  3. Value比...更快Manager.

警告

顺便说一句,如果可能的话,应该避免跨进程/线程共享数据.上面的代码可能会按预期运行,但会增加执行所需的时间foo,事情会变得奇怪.比较以上与:

def foo(data, name=''):
    print type(data), data.value, name
    for j in range(1000):
        data.value += 1
Run Code Online (Sandbox Code Playgroud)

你需要一个Lock能够正常工作的东西.

我对所有这些都不是特别了解,所以也许其他人会来并提供更多的见解.我想我会提供一个答案,因为这个问题没有引起人们的注意.希望有所帮助.

  • @ChrisP我迟到了,但你怎么建议在一台机器上跨进程共享一个简单的int变量?我对IO绑定工作者使用多处理(直到我学习异步),并希望他们共享一个计数器,所以我知道他们经历了多少次迭代.回顾如何最好地实施? (3认同)
  • @ user2435611,[`Array`](http://docs.python.org/2/library/multiprocessing.html#multiprocessing.Array)将为您提供一个共享的ctypes数组.您需要事先确定要存储的数据类型,并提供[类型代码](http://docs.python.org/2/library/array.html#module-array).例如,`a = Array('c',10)`创建一个长度为10的单字符字符串数组.可以将新条目添加到数组中:`a [0] ='b'`.您不能将*any*值添加到数组中,请参阅[类型代码列表](http://docs.python.org/2/library/array.html#module-array). (2认同)