Восстановить процесс с помощью подпроцесса. Открыть?

1

У меня есть программа python, которая использует subprocess.Popen для запуска другого процесса (процесс python или что-то еще), и после его запуска я сохраняю дочерний PID в файл. Предположим, что внезапно родительский процесс умирает (из-за исключения или чего-то еще). Есть ли способ получить доступ к объекту, возвращенному Popen?

Я имею в виду, что основная идея состоит в том, чтобы сначала прочитать файл, и если он существует, и на нем есть ПИД-код, написанный на нем, то доступ к этому процессу каким-то образом, чтобы узнать код возврата или что-то еще. Если нет PID, запустите процесс с помощью Popen.

Спасибо большое!

  • 0
    Можете ли вы объяснить более подробно, зачем вам нужен объект Popen, какие методы Popen вы хотите вызвать и что родительский процесс делает с дочерним процессом (пишет в stdin, убивает его, проверяет, жив ли он еще?) ?
Теги:
popen

3 ответа

2
Лучший ответ

Объект Popen фактически является просто оболочкой для дочерних процессов PID, stdin, stdout и stderr, а также некоторыми удобными функциями для их использования.

Итак, возникает вопрос, почему вам нужен доступ к объекту Popen? Вы хотите установить связь с дочерним узлом, завершить его или проверить, все ли работает?

В любом случае невозможно вернуть объект Popen для уже запущенного процесса.

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

Самый простой способ поговорить с ребенком - открыть именованный канал из дочернего процесса, например. /etc/my _pipe, откройте этот именованный канал из родительского/управляющего процесса и напишите/прочитайте в/из него.

После быстрого просмотра python-daemon мне кажется, что python-daemon поможет вам демонировать ваш дочерний процесс, что сложно сделать правильно, но это не поможет вам в обмене информацией.

Но, как я уже сказал, я думаю, вам нужно рассказать нам, почему вам нужен объект Popen для дочернего процесса, прежде чем мы сможем вам помочь.

1

Если процесс умирает, все его открытые дескрипторы файлов закрыты. Сюда входят любые неназванные каналы, созданные popen(). Итак, нет, нет способа восстановить объект Popen только из PID. ОС даже не рассмотрит ваш новый процесс как родительский, поэтому вы даже не получите сигналы SIGCHLD (хотя waitpid() может работать).

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

Если вы хотите, чтобы ваш родительский процесс забирал место, где был остановлен ребенок, вам необходимо создать дочерний элемент для записи в файл, обычно в /tmp или /var/log, и записать его PID, как сейчас (обычное местоположение /var/run). (Имейте это, пишите в именованный канал, рискуя убить его с помощью SIGPIPE, как указано выше.) Если вы суффикс вашего имени файла с помощью PID, тогда процесс менеджера легко определить, какой файл принадлежит демону.

  • 0
    Зависит от обстановки вздоха - дети могут пережить своих родителей.
  • 0
    Спасибо за разъяснения.
0

Похоже, вы пытаетесь написать демона, и ему нужна поддержка pidfile. Вы не можете ошибиться в python-daemon.

Например:

import daemon
import lockfile
import os

with daemon.DaemonContext(pidfile=lockfile.FileLock('/var/run/spam.pid')):
    os.execl('/path/to/prog', args…)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню