Переустановка обработчика SIGCHLD
Я вижу пример обработчика SIGCHLD, например:
void child()
{
wait(0);
signal(SIGCHLD, child);
}
void server_main()
{
...
signal(SIGCHLD, child);
...
for(;;;) {
...
switch(fork()) {
...
}
}
В обработчике есть две части, которые меня смущают: 1). SIGCHLD пойман, когда ребенок заканчивается или остановлен. Тогда зачем нужно вызывать wait внутри обработчика? Сигнал уже поступает. 2). Зачем нужно переустанавливать обработчик SIGCHLD. Разве сигнал вызова не установит обработчик раз и навсегда?
Спасибо!
2 ответа
- SIGCHLD будет запущен, когда дочерний процесс завершит выполнение. Однако он все еще будет в таблице процессов (как так называемый процесс зомби), чтобы позволить родителю получить выходное значение дочернего элемента. призвание
wait()
очистит таблицу процессов от этого дочернего процесса. - Если вы только создаете
n
дочерние процессы, то нет никакой причины для того, чтобы обработчик сигнала оставался на месте, когда всеn
дочерние процессы умерли.
Я предлагаю вам взглянуть на sigaction
вместо этого, как поведение signal
варьируется между Unixes.
Разве сигнал вызова не установит обработчик раз и навсегда?
Вы не можете полагаться на это поведение; возможно, обработчик сигнала будет очищен, возможно, он сохранится. Это часть проблемы с исторической обработкой сигналов. signal(3)
man-страница в моей системе сообщает:
When a signal occurs, and func points to a function, it is
implementation-defined whether the equivalent of a:
signal(sig, SIG_DFL);
is executed or the implementation prevents some
implementation-defined set of signals (at least including
sig) from occurring until the current signal handling has
completed.
Ненадежные сигналы были почти заменены sigaction(2)
сигналы, представленные в SysVr4 и стандартизированные в POSIX.1-2001:
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};
int sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact);
К сожалению, их сложнее написать, но как только вы напишете код, вам не придется задумываться, нужно ли вам переустанавливать свой обработчик, и вам не придется беспокоиться о том, что сигнал придет через секунду. время при обработке сигнала.