Ответ 1
Блокировка отличается от игнорирования. Вы игнорируете сигнал, установив SIG_IGN
с помощью sigaction()
.
После того как сигнал генерируется ядром или процессом, ядро делает его ожидающим выполнения для некоторого процесса (ов). Говорят, что сигнал подается в процесс, как только процесс воздействует на сигнал. Процесс может блокировать сигнал, который оставляет ожидающий сигнал до его разблокировки. Сигнал, который не заблокирован, будет доставлен немедленно. Маска сигнала указывает, какие сигналы блокируются. Процесс может определять, какие сигналы ожидаются.
Большинство UNIX не будут ставить в очередь несколько экземпляров одного и того же ожидающего сигнала; только один экземпляр каждого сигнала может быть отложен.
Настройка действия сигнала на SIG_IGN
для ожидающего сигнала приведет к отбрасыванию отложенного сигнала независимо от того, заблокирован он или нет.
И маска сигнала процесса содержит набор сигналов, которые в настоящий момент заблокированы.
Когда процесс блокирует сигнал, возникновение сигнала сохраняется до тех пор, пока сигнал не разблокируется (блокированные сигналы не теряются, а игнорируемые сигналы теряются).
Ответ 2
Когда вы маскируете сигнал, он на самом деле сообщает ядру, что этот сигнал не будет передан процессу до тех пор, пока не будет его маска. Это не означает, что сигнал никогда не будет повторяться снова в контексте процесса. Он просто помещается в очередь. Обычно это делается, когда вы хотите получить сигнал, но не во время определенной операции. Маскированный сигнал обычно подразумевает , этот сигнал может что-то значить для меня, но пусть он ждет, если он приходит до того, как я закончу с этой работой.
Пропущенный сигнал обычно означает, что сигнал не нужен для процесса.
#include<stdio.h>
#include<signal.h>
#include<sys/types.h>
int main()
{
sigset_t test; //test signal set
alarm(1); //set alarm,SIGALRM generated after 1 second
sigemptyset(&test);
sigaddset(&test,SIGALRM);
sigprocmask(SIG_SETMASK,&test,NULL); //mask sigalrm
sleep(3); //sleep for 3 seconds ensuring the signal is generated and is waiting in the queue
sigprocmask(SIG_UNBLOCK,&test,NULL); //unblock
}
Это относится к случаю 1. Сигнал маскируется. Но Он лежит там, ожидая и доставляя, как только вам это нужно
Выход strace подтверждает это
alarm(1) = 0
rt_sigprocmask(SIG_SETMASK, [ALRM], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [ALRM], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [ALRM], NULL, 8) = 0
nanosleep({3, 0}, 0xbfee9ea4) = 0
rt_sigprocmask(SIG_UNBLOCK, [ALRM], NULL, 8) = 0
--- SIGALRM (Alarm clock) @ 0 (0) ---
+++ killed by SIGALRM +++
В то время как для второго случая
#include<stdio.h>
#include<signal.h>
int main()
{
alarm(1);
signal(SIGALRM,SIG_IGN);
sleep(3);
signal(SIGALRM,SIG_DFL);
return 0;
}
Страт o/p предлагает другую историю
alarm(1) = 0
rt_sigaction(SIGALRM, {SIG_IGN, [ALRM], SA_RESTART}, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({3, 0}, {2, 691998}) = ? ERESTART_RESTARTBLOCK (To be restarted)
--- SIGALRM (Alarm clock) @ 0 (0) ---
restart_syscall(<... resuming interrupted call ...>) = 0
rt_sigaction(SIGALRM, {SIG_DFL, [ALRM], SA_RESTART}, {SIG_IGN, [ALRM], SA_RESTART}, 8) = 0
exit_group(0) = ?
Сигнал получил доставлен, но ничего не произошло, кроме прерывания (и перезапуска сна).