生产者/消费者多生产者和单个消费者写入文件Python

时间:2011-09-01 04:44:57

标签: python file-io message-queue multiprocessing producer-consumer

我的要求类似于Multiple producers, single consumer 除了我需要它在python

我创建了一个产生5个并发进程的应用程序(我正在使用多处理库)。这5个进程独立生成dict格式的输出。

之前我将输出打印到控制台,但现在想将其输出到文件中。

我正在寻找一种模式,其中我的所有5个生成器都写入支持并发写入的共享队列。

一个消费者进程也可以访问此队列并从中消耗数据,并且能够在没有数据写入时等待,并在生产者完成任务时终止。

谢谢Anuj

2 个答案:

答案 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()