У меня есть процесс и вы хотите начать его снова, когда он будет убит. Для этого я начинаю процесс «опекуна» ребенка, который использует prctl(PR_SET_PDEATHSIG, SIGHUP);
, чтобы поймать убийство своего родителя и снова запустить его.Перезапустить убитый процесс с помощью SIGHUP
Вот код опекуна (протоколирование опущен):
void restart (int signal) {
if (getppid() == 1) {
if (fork() == 0) {
execl("./process", 0);
}
exit(1);
}
}
int main() {
prctl(PR_SET_PDEATHSIG, SIGHUP, NULL, NULL, NULL);
struct sigaction new_action, old_action;
new_action.sa_handler = restart;
sigemptyset (&new_action.sa_mask);
new_action.sa_flags = 0;
sigaction (SIGHUP, NULL, &old_action);
if (old_action.sa_handler != SIG_IGN) {
sigaction (SIGHUP, &new_action, NULL);
}
while (getppid() != 1) {
sleep(86400000);
}
return 0;
}
И родитель:
int main() {
if (fork() == 0) {
execl("./guardian", 0);
}
while (1) {
cout << "I am process\n";
sleep(1);
}
return 0;
}
У меня есть проблема в том, что он работает только один раз. Вот ps
выход, когда процесс был запущен первый раз:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
1012 13058 0.0 0.3 20244 1932 pts/1 Ss 08:22 0:00 -sh
1012 22084 0.0 0.1 11484 1004 pts/1 S+ 11:20 0:00 \_ ./process
1012 22085 0.0 0.1 11484 1000 pts/1 S+ 11:20 0:00 \_ [guardian]
1012 12510 0.0 0.3 20784 1712 pts/0 Ss 08:14 0:00 -sh
1012 22088 0.0 0.1 17412 1012 pts/0 R+ 11:20 0:00 \_ ps fu
, который хорошо выглядит. Затем я убиваю процесс с kill -9 22084
. И снова ps
выход:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
1012 13058 0.0 0.3 20244 1932 pts/1 Ss+ 08:22 0:00 -sh
1012 12510 0.0 0.3 20784 1712 pts/0 Ss 08:14 0:00 -sh
1012 22091 0.0 0.1 17412 1012 pts/0 R+ 11:21 0:00 \_ ps fu
1012 22089 0.0 0.1 11484 996 pts/1 S 11:20 0:00 [process]
1012 22090 0.0 0.1 11484 996 pts/1 S 11:20 0:00 \_ [guardian]
и когда я снова убить процесс kill -9 22089
опекуны не похоже, чтобы получить SIGHUP обратный вызов (я проверил из бревен, они опущены).
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
1012 13058 0.0 0.3 20244 1932 pts/1 Ss+ 08:22 0:00 -sh
1012 12510 0.0 0.3 20784 1712 pts/0 Rs 08:14 0:00 -sh
1012 22339 0.0 0.1 17412 1008 pts/0 R+ 11:27 0:00 \_ ps fu
1012 22090 0.0 0.1 11484 996 pts/1 S 11:20 0:00 [guardian]
Мой вопрос: почему опекун не получает SIGHUP?
Я подозреваю, что у него может быть что-то с фоновой группой процессов - когда процесс перезапускается, он находится в фоновом режиме (сравните S + и S в ps stat).
Это безумие. Вместо того, чтобы ребенок перезапускал родителя, почему бы просто не перезапустить родительский родитель? Вся система настроена так, что это тривиально. –
Да, я знаю, это не имеет особого смысла. Я воспроизвожу логику перезапуска процесса, которая у меня есть в приложении для Android. Android запускает приложение (родительский процесс), и этот процесс запускает опекун (дочерний процесс), который контролирует здоровье родителя. – lstipakov
@WilliamPursell: Не очень сумасшедший. Мое антивирусное программное обеспечение, по-видимому, делает что-то очень похожее. Убийство антивирусной программы - это стандартная хакерская уловка, поэтому антивирусная программа создает несколько экземпляров самого себя, и каждый из них создает опекуна, который следит за убитым родителем. Kill -9 является неблокируемым и необнаружимым - в случае уничтожения приложения. Он обнаруживается в дочерних процессах. –