python多处理中的共享变量

Posted

技术标签:

【中文标题】python多处理中的共享变量【英文标题】:Shared variable in python's multiprocessing 【发布时间】:2013-06-26 23:28:00 【问题描述】:

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

其次,是否可以不使用 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

【问题讨论】:

相关:eli.thegreenplace.net/2012/01/04/… 【参考方案1】:

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

manager = Manager()
for i in range(5):
    new_value = manager.Value('i', 0)

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)

总结一下:

    使用Manager 创建多个共享对象,包括字典和 列表。使用Manager 在网络上的计算机之间共享数据。 在没有必要共享信息时使用ValueArray 跨网络,ctypes 中的类型足以满足您的需求 需要。 ValueManager 快。

警告

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

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

您需要Lock 才能正常工作。

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

【讨论】:

@user2435611, Array 会给你一个共享的 ctypes 数组。您需要事先确定要存储的数据类型,并提供type code。例如,a = Array('c', 10) 创建一个长度为 10 的单字符字符串数组。可以将新条目添加到数组中,如下所示:a[0] = 'b'。您不能向数组添加 any 值,请参阅the list of type codes。 @ChrisP 我迟到了,但是您如何建议在一台机器上跨进程共享一个简单的 int 变量?我对 IO 绑定的工作人员使用多处理(直到我学习异步),并且希望有一个他们共享的计数器,这样我就知道他们经历了多少次迭代。建议如何最好地实施? @TravisLeleu 你找到解决方案了吗? 你应该使用Lock来保护Value,见eli.thegreenplace.net/2012/01/04/… 好像py3没有运行

以上是关于python多处理中的共享变量的主要内容,如果未能解决你的问题,请参考以下文章

Python多处理:如何将共享变量用于复杂类的列表?

在 python 多处理中传递共享内存变量

python 多进程共享全局变量之Manager()

python中各模块变量共享的问题。

多线程下处理变量共享的几种方式

python之多线程变量共享