第一个问题是 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
当您使用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
在网络上的计算机之间共享数据。
在 - 不需要共享信息时使用
Value
或Array
跨网络和ctypes
中的类型足以满足您的需求需要。 -
Value
比Manager
快。
警告
顺便说一下,如果可能的话,应该避免跨进程/线程共享数据。 上面的代码可能会按预期运行,但会增加执行foo
所需的时间,事情会变得奇怪。 将以上内容与以下内容进行比较:
def foo(data, name=''):
print type(data), data.value, name
for j in range(1000):
data.value += 1
您需要一个Lock
才能使其正常工作。
我对这一切并不是特别了解,所以也许其他人会来提供更多的见解。 我想我会提供一个答案,因为这个问题没有得到关注。