Ответ 1
У каждого процесса есть так называемая связанная с ним сигнальная маска, которая определяет набор заблокированных сигналов. Маска сигнала может быть запрошена или установлена с помощью setprocmask(2)
(для однопоточного кода) и pthread_sigmask(3)
(для многопоточного кода).
Всякий раз, когда сигнал поднимается (либо явно через kill(2)
, либо raise(3)
или с помощью какого-либо другого механизма, такого как повышение погрешности сегментации SIGSEGV
), сигнал проверяется против текущей маски сигнала. Если сигнал не заблокирован, тогда он действует немедленно: соответствующий соответствующий обработчик вызова вызывается, если он установлен, в противном случае выполняется действие по умолчанию (обычно выходящее с ненормальным статусом или игнорирование). Если сигнал заблокирован сигнальной маской, тогда состояние сигнала будет отложено, и программа продолжит выполнение.
Итак, рассмотрим следующую примерную программу:
#include <signal.h>
#include <stdio.h>
void on_sigusr1(int sig)
{
// Note: Normally, it not safe to call almost all library functions in a
// signal handler, since the signal may have been received in a middle of a
// call to that function.
printf("SIGUSR1 received!\n");
}
int main(void)
{
// Set a signal handler for SIGUSR1
signal(SIGUSR1, &on_sigusr1);
// At program startup, SIGUSR1 is neither blocked nor pending, so raising it
// will call the signal handler
raise(SIGUSR1);
// Now let block SIGUSR1
sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset, SIGUSR1);
sigprocmask(SIG_BLOCK, &sigset, NULL);
// SIGUSR1 is now blocked, raising it will not call the signal handler
printf("About to raise SIGUSR1\n");
raise(SIGUSR1);
printf("After raising SIGUSR1\n");
// SIGUSR1 is now blocked and pending -- this call to sigwait will return
// immediately
int sig;
int result = sigwait(&sigset, &sig);
if(result == 0)
printf("sigwait got signal: %d\n", sig);
// SIGUSR1 is now no longer pending (but still blocked). Raise it again and
// unblock it
raise(SIGUSR1);
printf("About to unblock SIGUSR1\n");
sigprocmask(SIG_UNBLOCK, &sigset, NULL);
printf("Unblocked SIGUSR1\n");
return 0;
}
Вывод:
SIGUSR1 received!
About to raise SIGUSR1
After raising SIGUSR1
sigwait got signal: 30
About to unblock SIGUSR1
SIGUSR1 received!
Unblocked SIGUSR1