Подтвердить что ты не робот

Обнаружение смерти родительского процесса

Как я могу обнаружить смерть родительского процесса в ОС Linux?

Если в родительском процессе называется fork(), который создает дочерний процесс. В родительском процессе я могу использовать системный вызов wait() для ожидающего завершаемого дочернего процесса и получения его статуса.

Но я не могу найти информацию о том, как дочерний процесс может обнаружить смерть родительского процесса?

4b9b3361

Ответ 1

Вы можете получить идентификатор родительского процесса, вызвав getppid(), а затем отправить сигнал 0 через kill(). Код возврата 0 указывает, что процесс все еще жив.

Как уже упоминалось @Ariel, getppid() будет либо возвращать pid исходного родительского элемента, либо init, который будет pid 1. Таким образом, вам нужно либо сохранить родительский pid, вызвав getppid() при запуске или позже проверьте, имеет ли ваш родитель pid 1.

В соответствии с этим ответом в Linux вы также можете обнаружить смерть родителя с помощью опции prctl() PR_SET_PDEATHSIG и самовыбранного сигнала.

Ответ 2

В моем Ubuntu 16.04.1 LTS getppid() не возвращает "1", но идентификатор процесса "/sbin/upstart --user" после того, как родительский kill, поэтому проверка getppid() == 1 не будет работать и getppid() следует сохранять при старте ребенка и позже сравнивать.

Ответ 3

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

  1. Перед вилкой откройте трубу() или сокет().
  2. После развилки,
    1. в родительском объекте закройте конец чтения канала или первый сокет.
    2. в дочернем случае закройте конец записи канала или второй сокет.
  3. В родительском хранилище оставьте оставшийся файловый дескриптор и забудьте об этом.
  4. В дочернем случае используйте любой из методов мультиплексированного ввода-вывода (выбор, опрос и т.д.), Чтобы проверить дескриптор на читаемость
  5. Если дескриптор становится читабельным, родитель почти наверняка умер, или какая-то редкая ошибка вызвала случайную запись, которую вы можете проверить, вызвав read(). Если родитель действительно мертв, read() вернет 0 байтов.

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