2015-09-16 3 views
1

У меня есть программа (скажем, «прог»), написанная на C, которая делает много числовых операций. Я хочу написать утилиту «driver» в python, которая параллельно запускает «prog» с различными конфигурациями, считывает свои выходы и записывает их в журнал. Есть несколько вопросов, которые следует принимать во внимание:Проектирование хорошей архитектуры для многопроцессорности python

  1. Все рода вещи могут испортиться в любое время, так протоколирование должно быть сделано как можно скорее после любого prog экземпляра заканчивается.
  2. Несколько prog s может закончить одновременно, ведение журнала должны быть сделаны, централизованные
  3. работники могут быть убиты каким-то образом и driver должен обрабатывать эту ситуацию должным образом
  4. все рабочие и регистратор должен быть расторгнуто правильно без тоннами цепочек вызовов, когда KeyboardInterrupt обрабатывается

первые два пункта заставляют меня думать, что все работники должны отправить свои результаты в какой-то централизованной logger работника, например, через multiprocessing.Queue. Но, похоже, третий пункт делает это решение плохим, потому что, если рабочий убит, очередь будет повреждена. Таким образом, очередь не подходит. Вместо этого я могу использовать несколько процессов для обработки труб (т. Е. Каждый рабочий подключен через трубу с помощью регистратора). Но тогда другие проблемы поднимают:

  1. чтение из трубы блокирующей операции так один регистратор не может читать асинхронно из нескольких рабочих
  2. если работник был убит, а труба повреждена, (использование темы?) как регистратор может диагностировать это?

P.S. Точка №4, по-видимому, может быть решена - a должен быть

  1. отключает обработку по умолчанию SIGINT во всех рабочих и регистраторах;

  2. добавить try except к основному процессу, который вызывает вызовы pool.terminate();pool.join() в случае обработки исключений SIGINT.

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

P.S. питон 2,7

+0

Мой совет - сначала прочитать эти две статьи - (1) http://www.jeffknupp.com/blog/2012/03/31/pythons-hardest-problem/ и (2) https: // www. jeffknupp.com/blog/2013/06/30/pythons-hardest-problem-revisited/. Первый объясняет, почему Python не может быть лучшим вариантом для параллелизма, а второй - некоторыми способами улучшения этого недостатка. – rbaleksandar

+0

@ rbaleksandar. Ха!Знаешь, я думал, что использование Threads - это не выход, но GIL может действительно решить проблему! Каждый рабочий запускает 'prog' с помощью subprocess.call (...) и после этого сохраняет вывод в какую-то общую переменную. Благодаря GIL запись в общую переменную будет абсолютно безопасной. Несмотря на блокировку потока, порожденная 'prog' будет работать параллельно. И не будет необходимости во всех этих громоздких инструментах обмена сообщениями между процессами. Как вы думаете? – DimG

+0

Можете ли вы изменить 'prog' или он исправлен, и мы не можем его трогать? Какой тип ввода и вывода он делает? –

ответ

1

Вы можете начать с ответа Приводимые здесь: https://stackoverflow.com/a/23369802/4323

Идея заключается в том, чтобы не использовать subprocess.call(), который блокирует, но вместо того, чтобы subprocess.Popen, который не является блокирующим. Установите stdout каждого экземпляра, например. a StringIO объект, который вы создаете для каждого prog ребенка. Возьмите все prog s, дождитесь их, напишите их вывод. Должно быть недалеко от кода, показанного выше.

Смежные вопросы