Обнаружьте, если процесс уже работает, и сотрудничайте с ним

Я пытаюсь создать программу, которая запускает пул процесса, скажем, 5 процессов, выполняет некоторую операцию, и затем выходит, но оставляет 5 процессов открытыми. Позже пользователь может запустить программу снова, и вместо него начинающий новые процессы, это использует существующие 5. В основном это - модель производителя-потребителя где:

  1. Число производителей варьируется.
  2. Число потребителей является постоянным.
  3. Производители могут быть запущены в разное время различными программами или даже различными пользователями.

Я использую встроенное multiprocessing модуль, в настоящее время в Python 2.6.4., но с намерением переместиться в 3.1.1 в конечном счете.

Вот основной сценарий использования:

  1. Начало состояния - никакое выполнение процессов.
  2. Пользователь запускает program.py operation - один производитель, пять потребителей, работающих.
  3. Операция завершается - пять потребителей, работающих.
  4. Пользователь запускает program.py operation - один производитель, пять потребителей, работающих.
  5. Пользователь запускает program.py operation - два производителя, пять потребителей, работающих.
  6. Операция завершается - один производитель, пять потребителей, работающих.
  7. Операция завершается - пять потребителей, работающих.
  8. Пользователь запускает program.py stop и это завершается - никакое выполнение процессов.
  9. Пользователь запускает program.py start и это завершается - пять потребителей, работающих.
  10. Пользователь запускает program.py operation - один procucer, пять потребителей, работающих.
  11. Операция завершается - пять потребителей, работающих.
  12. Пользователь запускает program.py stop и это завершается - никакое выполнение процессов.

Проблема, которую я имею, состоит в том, что я не знаю, где запустить на:

  1. Обнаружение, что потребительские процессы работают.
  2. Получение доступа к ним из ранее несвязанной программы.
  3. Выполнение 1 и 2 межплатформенным способом.

После того как я могу сделать это, я знаю, как справиться с процессами. Должен быть некоторый надежный способ обнаружить существующие процессы, так как я видел, что Firefox делает это, чтобы препятствовать тому, чтобы несколько экземпляров Firefox работали, но я понятия не имею, как сделать это в Python.

8
задан Imagist 8 January 2010 в 22:21
поделиться

3 ответа

[

] Есть пара общих способов сделать Ваш пункт #1 (обнаружение запущенных процессов), но для их использования сначала нужно слегка подкорректировать ментальную картину того, как эти фоновые процессы запускаются при первом вызове программы.[

] [

]Думайте о первой программе не как о запуске пяти процессов и последующем выходе, а как о обнаружении того, что это первый запущенный экземпляр и []не[] выход из программы. Она может создать файловую блокировку (один из распространенных подходов для предотвращения множественных случаев запуска приложения), или просто привязать к какому-либо сокету (другой распространенный подход). Любой подход поднимет исключение во втором экземпляре, который затем знает, что он не первый и может переориентировать свое внимание на обращение к первому экземпляру.[

] [

]Если вы используете []мультипроцессорную обработку [], вы должны быть в состоянии просто использовать поддержку []Менеджера [], которая включает привязку к сокету, чтобы действовать в качестве сервера.[

] [

]Первая программа запускает процессы, создает очереди, прокси, или что-то в этом роде. Она создает Менеджер для разрешения доступа к ним, возможно, разрешая []удалённый доступ [].[

] [

]Последующие вызовы сначала пытаются связаться с указанным сервером/Менеджером на предопределённом сокетах (или используя другие методы, чтобы обнаружить розетку, на которой она находится). Вместо того, чтобы делать вызов []server_forever()[], они []connect()[] и общаются, используя обычные механизмы []multiprocessing[].[

].
2
ответ дан 6 December 2019 в 00:07
поделиться
[

] Взгляните на эти различные механизмы обнаружения сервисов: []http://en.wikipedia.org/wiki/Service_discovery[][

] [

]Основная идея заключается в том, что каждый потребитель регистрирует услугу, когда начинает. Производитель проходит процесс обнаружения, когда он начинает. Если он находит потребителей, он привязывается к ним. Если он не находит их, он запускает новых потребителей. В большинстве из этих систем службы, как правило, также могут публиковать свойства, так что каждый потребитель может уникально идентифицировать себя и дать другую информацию открывающему себя производителю.[

] [

]Bonjour/zeroconf довольно хорошо поддерживается кроссплатформенность. Вы даже можете настроить Safari, чтобы показать вам zeroconf услуг в вашей локальной сети, так что вы можете использовать это для отладки рекламы службы для потребителей. Одно из побочных преимуществ такого подхода заключается в том, что вы можете легко запускать производителей на разных машинах, нежели потребители[

].
1
ответ дан 6 December 2019 в 00:07
поделиться

Вам нужна модель клиент-сервер в локальной системе. Вы можете сделать это, используя сокеты TCP / IP для связи между вашими клиентами и серверами, но быстрее использовать локальные именованные каналы, если у вас нет необходимости общаться по сети.

Основные требования к вам, если я правильно понял, таковы:
1. Производитель должен иметь возможность порождать потребителей, если таковые еще не существуют.
2. Производитель должен иметь возможность общаться с потребителями.
3. Производитель должен уметь находить уже существующих потребителей и общаться с ними.
4. Даже если производитель завершит работу, потребители должны продолжать работать.
5. Более чем один производитель должен иметь возможность общаться с потребителями.

Давайте рассмотрим каждый из них один за другим:

(1) - это простая проблема создания процесса, за исключением того, что потребительские (дочерние) процессы должны продолжать работать, даже если производитель (родитель) завершает свою работу. См. (4) ниже.

(2) Производитель может общаться с потребителями, используя именованные каналы . См. os.mkfifo () и unix справочную страницу из mkfifo () для создания именованных каналов.

(3) Вам необходимо создать именованные каналы из процессов-потребителей по хорошо известному пути, когда они начнут работать. Производитель может узнать, работают ли какие-либо потребители, поискав эту хорошо известную трубу (трубы) в том же месте. Если канал (-ы) не существует, потребители не работают, и производители могут их порождать.

(4) Для этого вам нужно использовать os.setuid () и заставить процессы-потребители действовать как демон. См. Справочную страницу по unix из setsid ().

(5) Это непросто. Несколько производителей могут связываться с потребителями, используя один и тот же именованный канал, но вы не можете передать больше, чем «PIPE_BUF» данных от производителя к потребителю, если вы хотите надежно определить, какой производитель отправил данные, или если вы хотите предотвратить какое-то чередование данных от разных производителей.

Лучший способ выполнить (5) - заставить потребителей открывать именованный канал «control» (/tmp/control.3456, 3456 - это pid потребителя) при выполнении. Производители сначала настраивают канал связи, используя «контрольную» трубу. Когда производитель подключается, он отправляет свой pid, скажем, «1234», потребителю по каналу «control», который сообщает потребителю создать именованный канал для обмена данными с производителем, скажем, «/tmp/data.1234». Затем производитель закрывает канал «control» и открывает «/tmp/data.1234» для связи с потребителем. Каждый потребитель может иметь свои собственные «управляющие» каналы (используйте идентификаторы потребителей, чтобы различать каналы разных потребителей), и каждый производитель получает свой собственный канал «данных». Когда производитель заканчивает , он должен очистить подключите свой канал передачи данных или попросите потребителя сделать это. Точно так же, когда потребитель заканчивает, он должен очистить свои контрольные трубы.

Проблема состоит в том, чтобы предотвратить одновременное подключение нескольких производителей к каналам управления одного потребителя. «Контрольный» канал здесь является общим ресурсом, и вам необходимо синхронизировать между разными производителями, чтобы получить к нему доступ. Используйте для этого семафоры или блокировку файла . См. Для этого модуль Python posix_ipc .

Примечание: я описал большую часть вышеперечисленного в терминах общей семантики UNIX, но все, что вам действительно нужно, это возможность создавать процессы-демоны, возможность создавать «именованные» каналы / очереди / что угодно, чтобы их можно было найти несвязанный процесс и возможность синхронизации между несвязанными процессами. Вы можете использовать любой модуль Python, который предоставляет такую ​​семантику.

1
ответ дан 6 December 2019 в 00:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: