我的要求类似于Multiple producers, single consumer 除了我需要它在python
我创建了一个产生5个并发进程的应用程序(我正在使用多处理库)。这5个进程独立生成dict格式的输出。
之前我将输出打印到控制台,但现在想将其输出到文件中。
我正在寻找一种模式,其中我的所有5个生成器都写入支持并发写入的共享队列。
一个消费者进程也可以访问此队列并从中消耗数据,并且能够在没有数据写入时等待,并在生产者完成任务时终止。
谢谢Anuj
答案 0 :(得分:1)
我在Python中实现了这种模式,其中一个管理程序进程生成了一堆进程,然后从所有进程中消耗了日志消息,并将这些日志消息写入一个日志文件中。
基本上,我使用execve来指定每个进程的stderr连接到PTY的进程。然后我的主管打开了所有主要的PTY并使用select
在循环中读取它们。 PTY由tty线路规则进行行缓冲,你可以在它们上使用readline进行非=阻塞读取。我相信我也在PTY上使用了fcntl来设置os.O_NONBLOCK。
效果很好。唯一的障碍是,当您从select poll返回时,您需要读取每个pty多行,否则您可能会丢失输出(假设您有一些收获子进程并重新启动)。通过读取每个PTY上可用的所有行,您还可以避免回溯与其他消息交错。
如果你真的需要发送对象而不是文本行,那么你最好使用真正的pub-sub消息系统,如AMQP或ZeroMQ。 AMQP是一个比你需要的更大的锤子,所以如果你希望建立很多类似的应用程序,只需检查一下。否则,请尝试更简单的0MQ http://www.zeromq.org/intro:read-the-manual,它只是一个消息库,使套接字更容易使用。
答案 1 :(得分:0)
因为您已经在使用多进程,所以您只需要Queue类
和一个示例(从队列文档中修改)
from multiprocessing import Process, Queue
def child(q, url):
result = my_process(url)
q.put(result)
if __name__ == '__main__':
q = Queue()
urls = [...]
children = []
for url in urls:
p = Process(target=child, args=(q,url))
p.start()
children.append(p)
for p in children:
p.join()
print q.get() #or write to file (might not be the answer from this child)
修改强> 对于每个孩子的多个答案,将最后一个for循环替换为:
while 0 != multiprocessing.active_children():
print q.get()