Каждый процесс имеет так называемую маску сигналов , связанную с ним, которая определяет набор сигналов, которые заблокированы . Сигнальная маска может быть запрошена или установлена с помощью setprocmask(2)
(для однопоточного кода) и pthread_sigmask(3)
(для многопоточного кода).
Всякий раз, когда сигнал повышается (либо явно через kill(2)
или raise(3)
, либо через какой-либо другой механизм, такой как повышение ошибки сегментации SIGSEGV
), сигнал проверяется по текущей маске сигнала. Если сигнал не заблокирован, то на него воздействуют немедленно: соответствующий обработчик сигнала вызывается, если он установлен, в противном случае выполняется действие по умолчанию (обычно выход с ненормальным состоянием или его игнорирование). Если сигнал блокируется маской сигнала, то состояние сигнала устанавливается на в ожидании , и программа продолжает выполнение.
Итак, рассмотрим следующий пример программы:
#include <signal.h>
#include <stdio.h>
void on_sigusr1(int sig)
{
// Note: Normally, it's 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's 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