如何在不传递引用的情况下通过Python中的SyncManager跨进程共享列表

如何在不传递引用的情况下通过Python中的SyncManager跨进程共享列表,python,ipc,python-multiprocessing,Python,Ipc,Python Multiprocessing,在python中,多处理模块提供了可以在进程之间生成共享列表/目录的管理器 但是,如果访问管理器的进程不是子进程,而是通过manager.connect连接到管理器,则使用这些共享对象时会出现问题 这里有一个非常基本的例子:我试图创建一个共享列表,它可以被一组进程访问。对于本例,我只是在两个终端窗口中两次启动相同的代码: 导入操作系统,时间 从multiprocessing.managers导入SyncManager def main()->无: 打印(f“我是进程{os.getpid()}”)

在python中,多处理模块提供了可以在进程之间生成共享列表/目录的管理器

但是,如果访问管理器的进程不是子进程,而是通过
manager.connect
连接到管理器,则使用这些共享对象时会出现问题

这里有一个非常基本的例子:我试图创建一个共享列表,它可以被一组进程访问。对于本例,我只是在两个终端窗口中两次启动相同的代码:

导入操作系统,时间
从multiprocessing.managers导入SyncManager
def main()->无:
打印(f“我是进程{os.getpid()}”)
打印(f“正在启动代理服务器…”)
manager=SyncManager(地址=(“127.0.0.1”,8000),authkey=b“noauth”)
尝试:
manager.start()#如果同步进程不存在,将启动同步进程
除:
manager.connect()#如果它确实存在,请改为连接到它
打印(f“代理服务器已启动/已连接”)
#希望生成每个进程都可以访问的共享列表。
sharedList=manager.list()#这会生成一个新的列表,因此每个进程都有自己的列表,这不是我想要的
sharedList.append(os.getpid())
时间。睡眠(20)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
main()
Pythons似乎与我正在寻找的类似,但是没有关于如何获得
Manager.list
Manager.dict
共享的信息


注意:我也非常乐意共享一个名称空间对象。

以下是我最终解决问题的方法。您需要手动生成一个拥有共享列表的管理器进程

导入多处理
从多处理导入进程
导入操作系统、时间、系统
从multiprocessing.managers导入SyncManager、ListProxy
从队列导入队列
类共享存储(SyncManager):
通过
def ManagerProcess():
sys.stdout=open(os.devnull,'w')
sys.stderr=open(os.devnull,'w')
l=列表()
SharedStorage.register('get_list',lambda:l,ListProxy)
尝试:
ss=SharedStorage(地址=(“127.0.0.1”,8000),authkey=b“noauth”)
ss.get_server().serve_ever())
除操作错误外:
#无法侦听端口-已在使用中。
通过
def main()->无:
打印(f“我是进程{os.getpid()}”)
打印(f“正在启动代理服务器…”)
mainProcess=multiprocessing.Process(target=ManagerProcess,daemon=True)
mainProcess.start()
SharedStorage.register('get_list')
manager=SharedStorage(地址=(“127.0.0.1”,8000),authkey=b“noauth”)
manager.connect()
打印(f“代理服务器已启动/已连接”)
#必需-请参阅https://bugs.python.org/issue7503
多处理。当前进程().authkey=b“noauth”
#获取对共享列表对象的引用
shared\u list=manager.get\u list()
shared_list.append(os.getpid())
对于共享_列表中的i:
印刷品(一)
时间。睡眠(20)
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
main()

这可以安全地运行多次,因为后续进程生成的管理进程将在无法侦听端口后退出。

我的想法是,您必须在两个管理器之间建立某种通信通道。这个问题似乎解释了如何做到这一点:。完成后,我想知道是否可以让一方的经理创建一个共享列表,然后通过通信渠道将其发送给另一位经理(实际上是对它的引用)。然后,另一个管理器应该为该对象创建一个代理,您可以在该端使用该代理。