Перезапустите убитый процесс с SIGHUP - PullRequest
2 голосов
/ 10 февраля 2012

У меня есть процесс, и я хочу запустить его снова, когда он будет убит.Чтобы добиться этого, я запускаю дочерний процесс «хранитель», который использует prctl(PR_SET_PDEATHSIG, 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 output:

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 guardian, похоже, не получает обратный вызов 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).

1 Ответ

4 голосов
/ 10 февраля 2012

Похоже, SIGHUP заблокирован, пока вы работаете с обработчиком сигнала SIGHUP.fork() и exec() наследуют маску сигнала, поэтому ваш второй опекун никогда не получит ее снова.

Разблокирует SIGHUP в обработчике сигнала после fork() до exec() parent.

...