但是当我尝试将其与Pool.map
使用
from multiprocessing import Value, Pool, Manager
def f(args):
n, = args
n.value = 1
if __name__ == '__main__':
n = Value('d', 0.0)
# n = Manager().Value('d', 0.0) # can workaround the error
with Pool(1) as pool:
pool.map(f, [(n,)])
# RuntimeError: Synchronized objects should only be shared between processes through inheritance
print(n.value)
:时出现错误
Process.start()
由于有很多启动多进程的方法,我从未阅读过所有文档或尝试过。只是想知道导致后者失败的记录
Pool.map
和
Manager().Value
的本质区别是什么?
我搜索和学到了with Manager() as
可以解决。但是它的魔力是什么?由于我不使用Manager().Value
风格。如果在两种情况下(也许是所有)方案中都起作用,为什么需要设计另一个只能部分工作的设计?
multiprocessing.Value
使用共享内存。从概念上讲,没有技术原因在孩子开始后不能传递给他们,这只是事实,它可以大大简化所有实现,并可以提高安全性。 (如果您可以在施工后可以将其传递给儿童,则可能避免进行一些检查时间的检查时间)
例如,某些操作系统允许您创建匿名的私人共享内存,只有儿童进程才能在启动上继承,但是您只能使用可以在启动之后传递的命名共享内存,因此没有技术原因使它变得不可能。您可以使用
multiprocessing.Value
参数将他们传递给
Pool
子的孩子。
initializer
Manager
不使用共享内存,这是一个在本地存储对象并使用插座进行通信的过程。您产生了一个经理流程,其他流程将数据包发送给它说
args=(2,)
global_var=<Synchronized wrapper for c_double(0.0)>
n.value=2.0
和
get this value
。它要慢得多。但是,任何过程都可以连接到儿童过程(如果您将其端口设置为公共端口,甚至不在同一PC上)。它使用一些加密来解决潜在的漏洞。