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

生产者/消费者多生产者和单个消费者写入Python文件,python,file-io,message-queue,multiprocessing,producer-consumer,Python,File Io,Message Queue,Multiprocessing,Producer Consumer,我的要求与 除了我需要python版本 我创建了一个生成5个并发进程的应用程序(我使用的是多进程库)。这5个进程独立地生成dict格式的输出 早些时候,我将输出打印到控制台,但现在希望将其输出到一个文件 我正在寻找一种模式,在这种模式中,我的5个生产者都将写入一个支持并发写入的共享队列 单个使用者进程也可以访问此队列并使用其中的数据,如果没有数据可写,则可以等待,并在生产者完成任务时终止 感谢Anuj我已经在Python中实现了这个模式,其中一个主管进程生成一组进程,然后使用所有进程的日志消息,

我的要求与 除了我需要python版本

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

早些时候,我将输出打印到控制台,但现在希望将其输出到一个文件

我正在寻找一种模式,在这种模式中,我的5个生产者都将写入一个支持并发写入的共享队列

单个使用者进程也可以访问此队列并使用其中的数据,如果没有数据可写,则可以等待,并在生产者完成任务时终止


感谢Anuj

我已经在Python中实现了这个模式,其中一个主管进程生成一组进程,然后使用所有进程的日志消息,并将这些日志消息写入单个日志文件

基本上,我使用execve对进程进行spawan,并指定每个进程的stderr连接到PTY。然后,我的主管打开所有主PTY,并使用
select
循环读取它们。PTY由tty行规程进行行缓冲,您可以在PTY上使用readline进行非阻塞读取。我相信我也在PTY上使用了fcntl来设置os.O_非块

效果很好。唯一的问题是,当您从select轮询返回时,每个pty需要读取多行数据,否则您可能会丢失输出(假设您有一些内容正在获取子进程并重新启动)。通过读取每个PTY上可用的所有行,您还可以避免回溯与其他消息交叉


如果确实需要发送对象而不是文本行,那么最好使用真正的发布子消息传递系统,如AMQP或ZeroMQ。AMQP是一个比你需要的大得多的锤子,所以如果你希望构建很多类似的应用程序,那么只需检查一下。否则,请尝试更简单的0MQ,它只是一个消息传递库,使套接字更易于使用。

因为您已经在使用多进程,所以只需要队列类

和一个示例(从队列文档中修改)

编辑: 对于每个子项的多个答案,将最后一个For循环替换为:

while 0 != multiprocessing.active_children():
    print q.get()

您还可以在合并过程中进行一些行缓冲,根据需要在日志输出中插入横幅,这样您就可以保持输出笔直。谢谢Micheal,在我的情况下,我实际上没有日志,我的每个进程都将被赋予一个URL,并使用SeleniumWebDriverAPI导航URL,一旦完成,我将以dict格式从DOM中获取某些数据。每个进程将从输入url生成一个dict,并将其放入队列中,插入顺序并不重要。在写入时,单个使用者将尝试从队列和块中获取5个对象(如果不可用),并将写入文件。如果你还可以包括一些代码,那么你的回答会很好。不应该是这个孩子。追加(子)是孩子。追加(P)也请让我知道当我从队列中取出对象时的行为,让我们考虑当队列很大时的情景。我希望连续轮询队列以获取结果,并在队列为空时等待它。在代码中使用多处理队列时接受答案。但是对于子进程管理,我在父进程中有一个单独的监视线程,该线程持续监视进程状态,并返回输出以检查长时间子进程是否死机或阻塞。实际上,我在子进程中spwan firefox和XVFB实例,而firefox是firefox它往往会经常挂起并使我的子进程没有响应:)p.join()将阻止等待子进程q.put最终导致死锁,这在
while 0 != multiprocessing.active_children():
    print q.get()