fork () и как сигналы доставляются процессам


13

Я программирую, что я написал в C fork () от дочернего процесса. Ни один процесс не прекратится. Если я запустил программу из командной строки и нажал control-c, какой процесс (ы) получит сигнал прерывания?

Ответы:


20

Почему бы нам не попробовать и посмотреть? Вот тривиальная программа, которая используется signal(3)для перехвата SIGINTкак родительского, так и дочернего процесса и распечатывает сообщение, идентифицирующее процесс, когда он прибывает.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
void parent_trap(int sig) {fprintf(stderr, "They got back together!\n");}
void child_trap(int sig) {fprintf(stderr, "Caught signal in CHILD.\n");}
int main(int argc, char **argv) {
    if (!fork()) {
        signal(SIGINT, &child_trap);
        sleep(1000);
        exit(0);
    }
    signal(SIGINT, &parent_trap);
    sleep(1000);
    return 0;
}

Давайте назовем это test.c. Теперь мы можем запустить его:

$ gcc test.c
$ ./a.out
^CCaught signal in CHILD.
They got back together!

Сигналы прерывания, генерируемые в терминале, доставляются в активную группу процессов, которая здесь включает в себя как родительский, так и дочерний процесс . Вы можете видеть, что оба child_trapи parent_trapбыли выполнены, когда я нажал Ctrl- C.

Существует долгое обсуждение взаимодействия forkи сигналов в POSIX . Наиболее существенная часть этого здесь - то, что:

Сигнал, отправляемый группе процессов после fork (), должен быть доставлен как родителю, так и потомку.

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

Другие полезные моменты:

  • Сигнал, созданный вручную и отправленный отдельному процессу (возможно, с помощью kill), будет доставлен только этому процессу, независимо от того, является ли он родительским или дочерним процессом.
  • Порядок, в котором обработчики сигналов выполняются между процессами, не определен, поэтому вы не можете полагаться ни на одно из первых.
  • Если вы не определяете обработчик прерываний (или явно игнорируете сигнал), оба процесса просто завершают работу с SIGINTкодом (поведение по умолчанию).
  • Если один обрабатывает сигнал не смертельно, а другой - нет, тот, у которого нет обработчика, умрет, а другой продолжит.

Я предполагаю, что снаряды также могут мешать интересным образом? Если это сигнал, который они могут заманить в ловушку, он может отправить его своим детям? (И затем есть SIGHUP) (Все это может означать, что, хотя ОС не отправляет сигналы, дочерний процесс не может быть затронут сигналом для родителя ...)
— Герт ван ден Берг
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.