当向管理器注册多个队列时,最终会出现一个队列



考虑:

from multiprocessing import Queue
from multiprocessing.managers import SyncManager
def make_manager(q_names, port):
qs = [Queue() for _ in q_names]
class MyManager(SyncManager):
pass
for q_name, q in zip(q_names, qs):
MyManager.register(q_name, callable=lambda: q)
auth = b'myauth'
try:
manager = MyManager(address=('', port), authkey=auth)
manager.start()
except:
print('Could not start manager')
return manager
manager = make_manager(['aa', 'bb'], 8000)
print(manager.aa())
print(manager.bb())

输出为:

<multiprocessing.queues.Queue object at 0x7f7ed1c83eb0>
<multiprocessing.queues.Queue object at 0x7f7ed1c83eb0>

为什么两个方法都返回相同的队列?

更新:我发现问题在于lambda如何捕获。这里有一个例子来说明:

ll = []
for i in range(2):
ll.append(lambda: i)
for l in ll:
print(l()) # 1

我仍然不确定如何绕过这个问题,但会再次搜索,因为它与multiprocessing无关。

更新:发现它:循环中的Lambda

关于解决方法,您可以将qs更改为:

qs = [Queue for _ in q_names]

并将lambda更改为该

lambda: q()

由于我无法访问UNIX设备,我无法对此进行测试,所以对持保留态度

我自己的解决方案如链接的帖子所示:

def make_manager(q_names, port):
class MyManager(SyncManager):
pass
for q_name in q_names:
q = Queue()
MyManager.register(q_name, callable=lambda q=q: q)
auth = b'myauth'
try:
manager = MyManager(address=('', port), authkey=auth)
manager.start()
except:
print('Could not start manager')
return manager

最新更新