sigsuspend (), заменить набор или добавить? - PullRequest
1 голос
/ 18 июля 2011

Согласно справочной странице sigsuspend (), он заменит текущую маску сигнала, установленную на 1-й параметр. В APUE я видел пример следующим образом. Код может быть слишком длинным, но я не хочу ничего пропустить.

int pr_mask(char *s)
{
    sigset_t sigset;

    sigprocmask(0, NULL, &sigset);

    printf("%s: ", s);

    if(sigismember(&sigset, SIGINT)) printf("SIGINT ");
    if(sigismember(&sigset, SIGQUIT)) printf("SIGQUIT ");
    if(sigismember(&sigset, SIGUSR1)) printf("SIGUSR1 ");
    if(sigismember(&sigset, SIGALRM)) printf("SIGALRM ");
    /* ..... */

    printf("\n");
    return 0;
}

void sig_quit(int signo)
{
    pr_mask("in sig quit");
}

int main()
{
    sigset_t new, old, tempset;

    signal(SIGQUIT, sig_quit);

    sigemptyset(&tempset);
    sigaddset(&tempset, SIGINT);

    sigemptyset(&new);
    sigaddset(&new, SIGQUIT);
    sigprocmask(SIG_BLOCK, &new, &old);

    pr_mask("in critical section");
    /* critical section */

    sigsuspend(&tempset);
    pr_mask("after return form sigsuspend");

    sigprocmask(SIG_UNBLOCK, &new, NULL);
    pr_mask("program exit");

    return 0;
}

Вывод:

in critical section: SIGQUIT 
in sig quit: SIGINT SIGQUIT 
after return form sigsuspend: SIGQUIT 
program exit: 

Проблема во второй строке. SIGQUIT все еще находится в наборе маски сигнала.

Должно ли это быть только SIGINT, поскольку sigsuspend уже заменил маску сигнала на tempset, который установлен только на SIGINT?

Ответы [ 2 ]

2 голосов
/ 18 июля 2011

При выполнении обработчика SIGQUIT, сам SIGQUIT блокируется. Это сделано для того, чтобы избежать повторного входа в обработчик случайно ...

Из спецификации POSIX для подписи (которую вы действительно должны использовать вместо signal):

Когда сигнал перехватывается функцией перехвата сигнала, установленной sigaction (), новая маска сигнала вычисляется и устанавливается на время действия функции перехвата сигнала (или до вызова sigprocmask () или sigsuspend ( ) сделан). Эта маска формируется за счет объединения маски текущего сигнала и значения sa_mask для доставляемого сигнала, если только не установлены SA_NODEFER или SA_RESETHAND, а затем включая доставляемый сигнал.

Спецификация POSIX для сигнала немного менее конкретна:

Когда возникает сигнал, и func указывает на функцию, это определяется реализацией, является ли эквивалент:

сигнал (sig, SIG_DFL);

выполняется или реализация предотвращает появление некоторого определенного реализацией набора сигналов (по крайней мере, включая sig ) до тех пор, пока текущая обработка сигналов не будет завершена.

Таким образом, для ОС допустимо просто добавлять сигнал в маску на время функции обработки сигнала, и, очевидно, именно это делает Linux.

0 голосов
/ 27 апреля 2014

, поскольку вывод «in sig quit: SIGINT SIGQUIT» печатается при выполнении обработчика SIGQUIT. Это добавит SIGQUIT к маске сигнала, что означает, что текущая маска становится объединением & tempset и SIGQUIT.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...