Базовые сигналы UNIX не ставятся в очередь - одновременно может ожидаться только один (для данного потока).
Если два дочерних процесса завершаются одновременно, и, таким образом, их SIGCHLD доставляются в одно и то же"время, ваш процесс будет иметь только один ожидающий сигнал.
wait
ing в цикле после получения SIGCHLD является давно установившейся техникой для компенсации того факта, что SIGCHLDможет быть "потерян".Переместите объявление «Дитя закончено! \ N» в цикл, который вызывает wait
, и вы получите точный счет.
ОБНОВЛЕНИЕ
Если вы должны В самом обработчике вы можете вызвать wait
внутри обработчика, поскольку он безопасен для асинхронного сигнала :
static void CHLDHandler(int sig)
{
static char child[] = "Child finished!\n";
int save_errno = errno;
while (waitpid((pid_t)-1, NULL, WNOHANG) > 0) {
write(STDERR_FILENO, &child, sizeof(child) - 1); // don't write the terminating NULL
}
errno = save_errno;
}
В этом случае я бы не установите SA_NODEFER, поскольку другой SIGCHLD может прерывать (EINTR) вызовы waitpid
или write
.