Разница в обработке сигналов в UNIX

Есть ли разница между маскировкой сигнала с использованием sigprocmask() и игнорированием сигнала с помощью signal(<signal>, SIG_IGN)?

Ответы

Ответ 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)                           = ?

Сигнал получил доставлен, но ничего не произошло, кроме прерывания (и перезапуска сна).