Я программирую, что я написал в C fork () от дочернего процесса. Ни один процесс не прекратится. Если я запустил программу из командной строки и нажал control-c, какой процесс (ы) получит сигнал прерывания?
Почему бы нам не попробовать и посмотреть? Вот тривиальная программа, которая используется 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
кодом (поведение по умолчанию).