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