44

First question is what is the difference between Value and Manager().Value?

Second, is it possible to share integer variable without using Value? Below is my sample code. What I want is getting a dict with a value of integer, not Value. What I did is just change it all after the process. Is there any easier way?

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
4

1 回答 1

60

使用时,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)

总结一下:

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

警告

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

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

您需要 aLock才能使其正常工作。

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

于 2013-06-30T19:07:01.827 回答