2016-04-17 2 views
0

В последнее время я занимаюсь обработкой сигналов на Linux и прочитал все концепции, связанные с обработкой сигналов. Один вопрос, который перерабатывает мою голову, заключается в том, что сигнал в наборе sigtimedwait() не доставляется, пока процесс разблокирован. Мой код выглядит следующим образом: -Сигналы в параметре «set» sigtimedwait() не доставляются

#include <signal.h> 
#include <stdlib.h> 
#include <string.h> 
#include <stdio.h> 
#include <errno.h> 
void sighandler1(int sig) 
{ 
     printf("SIGINT caught\n"); 
} 
void sighandler2(int sig) 
{ 
     printf("SIGTSTP caught\n"); 
} 
void sighandler3(int sig) 
{ 
     printf("SIGALRM caught\n"); 
} 

int main() 
{ 

    sigset_t s1,s2; 

    struct sigaction act1,act2,act3; 

    int ret; 

    sigemptyset(&s1);// The bit-mask s1 is cleared 
    sigaddset(&s1,SIGINT);//Add SIGINT to the bit-mask s1 

    sigemptyset(&s2);// The bit-mask s2 is cleared 
    sigaddset(&s2,SIGALRM);//Add SIGALRM to the bit-mask s2 

    sigprocmask(SIG_BLOCK,&s2,NULL);//Signal(s) in s2 blocked 

    act1.sa_handler = sighandler1; //function pointer pointing to the signal handler 
    act1.sa_flags = 0;   

    sigaction(SIGINT,&act1,NULL); // installing the action 
           // for SIGINT 

    act2.sa_handler = sighandler2; //function pointer pointing to another signal handler 
    act2.sa_flags = 0;   // no flags 


    sigaction(SIGTSTP,&act2,NULL); // installing the action 
           // for SIGTSTP 
    act3.sa_handler = sighandler3; //function pointer pointing to another signal handler 
    act3.sa_flags = 0;   // no flags 


    sigaction(SIGALRM,&act3,NULL); // installing the action for SIGALRM 

    sigprocmask(SIG_SETMASK,&s1,NULL); //Signals in s1 blocked and other signals unblocked 
    printf("sigprocmask() called with SIG_SETMASK on s1,which contains SIGINT\n"); 
    printf("Blocked on sigtimedwait() with s1\n"); 
    if(sigtimedwait(&s1,NULL,NULL) < 0) 
     { 
       if(errno == EINTR) 
       printf("Some other signal caught\n"); 
     } 
    printf("This is a process. You can pass signal to it\n"); 

    while(1); 

} 

Чтобы быть более ясным вопросом, я назвал sigtimedwait в приведенном выше коде с «s1» в качестве параметра «набор». Этот набор содержит только сигнал SIGINT. Согласно странице man, sigtimedwait() блокирует процесс, пока один из сигналов в его наборе не будет доставлен. Я все в порядке с этим заявлением. Но почему обработчик SIGINT не вызывается, когда я передаю SIGINT, чтобы разблокировать процесс? С другой стороны, когда я передаю SIGALRM или SIGTSTP, которых нет в наборе, EINTR возвращается, как ожидалось, а также вызывается обработчик сигналов.

Для тех, кто хочет наблюдать за сценарием, может выполнить вышеуказанный код, а затем передать ему SIGINT. Они будут наблюдать, что процесс разблокируется без вызова обработчика. Почему обработчик не вызван? Я неверно истолковываю любую часть справочной страницы sigtimedwait() ??

+0

Может кто-нибудь, пожалуйста, разобраться в этом? Заранее спасибо. –

ответ

0

sigtimedwait, кажется, возвращает значение сигнала, вместо того, чтобы обработчик сигнала попасться:

switch(sigtimedwait(&s1,NULL,NULL)) 
{ 
    default: 
     printf ("Some other signal???"); 
     break; 
    case SIGINT: 
     printf ("We got SIGINT\n"); 
     break; 
    case -1: 
     perror ("sigtimedwait"); 
     break; 
} 
+0

Ожидается, что на man-странице: sigwaitinfo() удаляет сигнал из набора ожидающих сигналов и возвращает номер сигнала в качестве результата своей функции. Если аргумент info не равен NULL, то буфер, на который он указывает, используется для возврата структуры типа siginfo_t (см. Sigaction (2)), содержащей информацию о сигнале. –

+0

Тогда, как насчет следующего утверждения, упомянутого в первой строке описания в человеко-странице -. * sigwaitinfo() приостанавливает выполнение вызывающего потока, пока один из сигналов в наборе поставляются * Это делает скажем, что сигнал должен быть доставлен. Тем не менее, я вижу, что сигнал в наборе не доставляется, но сигналы * не в наборе * доставляются, а обработчик получает вызов. –

+0

Вы только блокируете SIGINT в своем вызове sigprocmask(), поэтому другие сигналы могут пройти (заставляя sigtimedwait возвращать -1 и устанавливая errno в EINTR). После sigtimedwait SIGINT по-прежнему заблокирован и не может быть получен. С принятой формулировкой они означают, что она больше не находится в очереди ядра. sigtimedwait - это приемник сигнала в этом случае. –

Смежные вопросы