Изменить родительский процесс процесса?

14

Можно ли изменить родительский процесс процесса? Если да, то как?

Например,

  • как screenудается прикрепить screenсеанс и процессы, выполняющиеся в нем, к различным процессам оболочки? Есть ли смена родительского процесса?

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

  • Я думал, disownчто процесс меняет родительский процесс процесса, просто потому, что название disownподразумевает это. Но я обнаружил, что это не так.

  • Клиент Emacs может подключиться к серверу Emacs на другой вкладке терминала. Есть ли смена родительского процесса?

Тим
источник
disownпросто удаляет данный дочерний элемент из внутреннего списка дочерних процессов оболочки. PPID ребенка остается тем из раковины. Оболочка забыла, что когда-либо начинала этот ребенок, но ядро ​​помнит.
Уоррен Янг
Процесс помнит своего родителя?
Тим
Если он хочет знать, он вызывает getppid(2), системный вызов и системные вызовы обрабатываются ядром. Программа может быть сбита с толку, если выполнить этот вызов, сохранить значение и затем использовать это значение после того, как его происхождение изменилось. Здесь есть шанс состояния гонки.
Уоррен Янг
Похоже, интересная новая функция ядра.
ChuckCottrill

Ответы:

14

Идентификатор родительского процесса (ppid) процесса не может быть изменен вне ядра; нет системного вызова setppid. Ядро изменит ppid на (pid) 1 только после завершения родительского процесса - если процесс не ответил на сигнал о том, что родительский процесс был завершен. Для того чтобы это произошло, потребность процесса, игнорируют различные сигналы ( SIGHUP, SIGTERMи т.д.) заранее.

screen(1)имеет очень элегантные средства обработки отсоединения и присоединения. При первом запуске screenвы фактически запускаете пользовательский интерфейс (пользовательский интерфейс), который по умолчанию создает демона (менеджер сеансов). У этого демона нет связанного с ним терминала, новой группы процессов ( setpgrp(2)), нового идентификатора сеанса ( setsid(2)). Демон, запущенный как SCREEN, затем создаст подпроцессы, подключенные к псевдотерминалам ( pty), затем мультиплексирует данные из ptys и ui ( screen). Подпроцессы думают, что они разговаривают с реальным терминалом.

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

Arcege
источник
Благодарю. Я добавил: «Клиент Emacs может подключаться к серверу Emacs на другой вкладке терминала. Есть ли смена родительского процесса?»
Тим
1
Каждый процесс имеет только одного родителя, пока родитель не умрет или не умрет. Если он умрет, то точка является спорным. Если родитель умирает, то PPID становится 1, initпроцесс. Это единственный раз, когда родительский процесс изменится - когда родительский процесс завершится. Подключение через межпроцессное взаимодействие (каналы, розетки и т. Д.) Не влияет на PPID.
Arcege
Как Emacs присоединяет клиента к серверу на разных вкладках терминала?
Тим
Сервер будет прослушивать сокет (обычно файл сокета домена UNIX) в ожидании соединений. Клиент (ы) откроет соединение на этом сокете. Вкладки не имеют отношения к взаимодействию между клиентом и сервером, это могут быть разные вкладки, разные эмуляции терминала (xterm vs rxvt vs терминал) или могут быть xemacs. Каждый клиент знает, где подключиться, чтобы оно могло быть откуда угодно.
Arcege
1
Идентификатор родительского процесса не всегда становится 1. Этот полученный абсолютизм мудрости был неправильным больше 3 лет, теперь.
JdeBP
-2

Я понимаю. Вам нужно изменить ядро, чтобы написать какой-то модуль для этого! Я думаю, что это будет полезно в некоторых случаях. Например, вы выполняете долгую тяжелую работу, они занимают много ресурсов в течение нескольких часов ... А когда система не отвечает (как обычно в этом случае), вы делаете некоторые непредсказуемые действия (из-за того, что вам нужно сделать, и вы не уверены, что нажимаете мыши в нужном месте, чтобы система не отвечала в течение длительного времени) и случайно убила родительский процесс. Система обычно убивает всех детей! Но если дочерний процесс является корневым, а родительский - только обычным пользователем, и действие делает также обычным пользователем, этот процесс ни в коем случае не убивается! И его родитель будет инициализирован с PID 1. И после того, как система наконец ответит, вы хотите восстановить иерархию. Но ты не можешь !!! Стандартно вы запускаете систему как root с терминала как обычный пользователь с su. Почему? Таким образом, чтобы получить все ошибки и предупреждения на консоли. Особенно утилита для обновления это GUI. Они получают эту информацию ни к чему ... Я помню, в Windows OS это можно сделать. Существуют специальные функции WinAPI. Почему в Linux это невозможно сделать? Это не ясно ... Это простая вещь !!!

user239712
источник