2013-06-29 126 views
17

第一个问题是Value和Manager()之间有什么区别?Value?python多处理中的共享变量

二,是否有可能不使用值共享整数变量? 以下是我的示例代码。我想要的是得到一个整数,而不是值的字典。我所做的只是在整个过程结束后进行更改。有没有更简单的方法?

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 
+0

相关:http://eli.thegreenplace.net/2012/01/04/shared-counter-with-pythons-multiprocessing –

回答

19

当您使用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. 使用ValueArray时没有必要通过网络共享信息 和​​类型足以满足您的需求 。
  3. ValueManager更快。

警告

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

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

你需要一个Lock正确地完成这项工作。

关于这一切,我并不是特别需要知道,所以也许别人会来,并提供更多的见解。我想我会提出一个答案,因为这个问题没有得到关注。希望有所帮助。

+0

我们可以给Array添加任何值吗?我无法向Array添加任何值。 – user2435611

+2

@ 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''。您不能将*任何*值添加到数组中,请参阅[类型代码列表](http://docs.python.org/2/library/array.html#module-array)。 – ChrisP

+0

那么我们应该事先决定数组的大小,不能扩大它呢?如果是这样,最好使用manager.list()。感谢您的帮助:) – user2435611