我想动态创建多个Process
es,其中每个实例都有一个来自其他实例的传入消息的队列,并且每个实例也可以创建新实例。所以我们最终得到一个互相发送的进程网络。每个实例都可以发送给其他人。如何在Python多重处理中动态创建每进程队列
下面的代码会做我想做的:它采用了Manager.dict()
存储队列,确保更新传播和Lock()
保护写访问的队列。但是,当添加新的队列时,它会抛出"RuntimeError: Queue objects should only be shared between processes through inheritance"
。
问题是,在启动时,我们不知道最终会需要多少队列,所以我们必须动态创建它们。但由于除了施工时我们不能分享队列,所以我不知道该怎么做。
我知道,一个可能性是使queues
一个全局变量,而不是管理一个传入到__init__
:这个问题的话,我的理解是,增加的queues
变量将不会传播到其他进程。
编辑我正在进化算法。 EA是一种机器学习技术。一个EA模拟一个“人口”,它随着适者生存,交叉和变异而演变。在平行 EA,因为在这里,我们也有人口之间的迁移,对应于进程间通信。岛屿也可以产生新的岛屿,所以我们需要一种在动态创建的进程之间发送消息的方式。
import random, time
from multiprocessing import Process, Queue, Lock, Manager, current_process
try:
from queue import Empty as EmptyQueueException
except ImportError:
from Queue import Empty as EmptyQueueException
class MyProcess(Process):
def __init__(self, queues, lock):
super(MyProcess, self).__init__(target=lambda x: self.run(x),
args=tuple())
self.queues = queues
self.lock = lock
# acquire lock and add a new queue for this process
with self.lock:
self.id = len(list(self.queues.keys()))
self.queues[self.id] = Queue()
def run(self):
while len(list(self.queues.keys())) < 10:
# make a new process
new = MyProcess(self.lock)
new.start()
# send a message to a random process
dest_key = random.choice(list(self.queues.keys()))
dest = self.queues[dest_key]
dest.put("hello to %s from %s" % (dest_key, self.id))
# receive messages
message = True
while message:
try:
message = self.queues[self.id].get(False) # don't block
print("%s received: %s" % (self.id, message))
except EmptyQueueException:
break
# what queues does this process know about?
print("%d: I know of %s" %
(self.id, " ".join([str(id) for id in self.queues.keys()])))
time.sleep(1)
if __name__ == "__main__":
# Construct MyProcess with a Manager.dict for storing the queues
# and a lock to protect write access. Start.
MyProcess(Manager().dict(), Lock()).start()
哇,这真的很有用,谢谢。我已经在用例上添加了一些关于原始问题的信息。队列的优点是不必考虑缓冲区,酸洗,不完整的“recv”等等。但是现在我可以看到,连接队列不是必需的:套接字可以很好地工作,只需要一些额外的工作。我把你的代码和改变了它:现在可以通过pickle发送对象,可以创建新的进程,并且每个新进程现在都会将*自身*添加到字典中。我将添加我的代码作为一个单独的答案。 – jmmcd
我真的很高兴能帮到你。 – stderr