Производитель / Потребитель Несколько производителей и один Потребитель записывает в File Python - PullRequest
2 голосов
/ 01 сентября 2011

Мои требования аналогичны Несколько производителей, один потребитель кроме того, что мне нужно в Python

Я создал приложение, которое порождает 5 одновременных процессов (я использую многопроцессорную библиотеку). Эти 5 процессов независимо производят вывод в формате dict.

Ранее я выводил вывод на консоль, но теперь хотел бы вывести его в файл.

Я ищу шаблон, в котором все мои 5 производителей пишут в общую очередь, которая поддерживает одновременные записи.

И один потребительский процесс, который также имеет доступ к этой очереди и использует данные из нее, с возможностью ожидания, если нет данных для записи, и завершения, когда производители завершают свою задачу.

Спасибо, Анудж

Ответы [ 2 ]

1 голос
/ 01 сентября 2011

Я реализовал этот шаблон в Python, где процесс супервизора порождает несколько процессов, а затем получает сообщения журнала от всех из них и записывает эти сообщения журнала в один файл журнала.

По сути, я использовал execve для запуска процессов, указанных для того, чтобы stderr для каждого процесса был подключен к PTY. Затем мой руководитель открыл все основные файлы PTY и использовал select для чтения из них в цикле. PTY-файлы буферизуются в строке дисциплиной tty, и вы можете использовать readline на них для неблокирующих чтений. Я считаю, что я также использовал fcntl в PTY для установки os.O_NONBLOCK.

Отлично работает. Единственная проблема в том, что вам нужно прочитать более одной строки на pty, когда вы вернетесь из опроса select, иначе вы можете потерять вывод (при условии, что у вас есть что-то, что вызывает дочерние процессы и перезапускается). Читая все строки, доступные в каждом PTY, вы также избегаете чередования трассировок с другими сообщениями.

Если вам действительно нужно отправлять объекты, а не текстовые строки, тогда вам лучше использовать настоящую систему обмена сообщениями pub-sub, такую ​​как AMQP или ZeroMQ. AMQP - намного больший молоток, чем вам нужно, поэтому проверяйте его, только если вы планируете создавать множество похожих приложений. В противном случае попробуйте более простую 0MQ http://www.zeromq.org/intro:read-the-manual, которая является просто библиотекой сообщений, которая значительно упрощает использование сокетов.

0 голосов
/ 01 сентября 2011

, поскольку вы уже используете многопроцессорность, все, что вам нужно, это класс очереди

и пример (измененный из документов очереди)

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()
...