我想動態創建多個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