apue中int sigsuspend(const sigset_t *sigmask)的深入理解

来源:互联网 发布:何老师都哭了知乎 编辑:程序博客网 时间:2024/06/05 10:28

关于sigsuspend() 这个函数想了很久,终于想明白了,这里写下自己的心得与体会。

有的是参考别人的帖子,加上自己的程序的调试!

 

事实求是:首先来代码,离开代码都是浮云!

 

code1:

 

#include "../../include/apue.h"
#include "../../include/error.c"
#include "../../include/prmask.c"

 static void sig_int(int);

 int main(void)
{
    sigset_t   newmask, oldmask, waitmask;

 

    if (signal(SIGINT, sig_int) == SIG_ERR)
       err_sys("signal(SIGINT) error");

 

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

 

    sigemptyset(&oldmask);
    sigaddset(&oldmask,SIGUSR1);

 

    sigemptyset(&waitmask);
    sigaddset(&waitmask,SIGUSR2);

 

     if(sigprocmask(SIG_SETMASK,&oldmask,NULL)<0) //set thecurrent maskin the process,oldmask=SIGSUR1

                               sys_sys("SIG_SETMASK error");

 

    /* block SIGINT and save current signal mask */
    if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0) 
//newmask=SIGINT,oldmask=SIGINT,SIGUSR1;
                               err_sys("SIG_BLOCK error");
 
   
/* critical region of code */
    pr_mask("in critical region: ");     //output: in critical region:SIGINT,SIGUSR1;

 

    /* allow all signals and pause */
    if (sigsuspend(&waitmask) != -1)     
//waitmask=SIGUSR2,This is wait for the other mask set in the current mask in the process.
       err_sys("sigsuspend error");

 

    pr_mask("after return from sigsuspend: ");   //output:after return from sigsuspend:SIGINT,SIGUSR1;

 

    /* reset signal mask which unblocks SIGINT */
    if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) 
//oldmask=SIGUSR1;
       err_sys("SIG_SETMASK error");

 

     /* and continue processing ... */
     pr_mask("oldmask in process :");             //output:oldmask in process :SIGUSR1;

 

   exit(0);
}

 static void sig_int(int signo)
{
    pr_mask("\nin sig_int: ");         
//output: in sig_int:SIGUSR2;
}

 

#gcc -g -o other_test_10.15 other_test_10.15.c

./other_test_10.15

 

output:

in critical region: SIGINT SIGUSR1

Ctrl+C

in sig_int: SIGUSR2
after return from sigsuspend:
SIGINT SIGUSR1
oldmask in process :SIGUSR1

 

 

 

code2:

#include "../../include/apue.h"
#include "../../include/error.c"
#include "../../include/prmask.c"

static void sig_int(int);

 int main(void)
{
    sigset_t   newmask, oldmask, waitmask;

 

    if (signal(SIGINT, sig_int) == SIG_ERR)
       err_sys("signal(SIGINT) error");

 

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

 

    sigemptyset(&oldmask);
    sigaddset(&oldmask,SIGUSR1);

 

    sigemptyset(&waitmask);
    sigaddset(&waitmask,SIGUSR2);

 

     if(sigprocmask(SIG_SETMASK,&oldmask,NULL)<0) //set the current mask in the process,oldmask=SIGSUR1

                err_sys("SIG_SETMASK error");

 

    /* block SIGINT and save current signal mask */
    if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)  //newmask=SIGINT,oldmask=SIGINT,SIGUSR1;
       err_sys("SIG_BLOCK error");

 

    /* critical region of code */
    pr_mask("in critical region: ");     //output: in critical region:SIGINT,SIGUSR1;

 

    /* allow all signals and pause */
    if (sigsuspend(&newmask) != -1)      //newmask=SIGINT
       err_sys("sigsuspend error");

 

    pr_mask("after return from sigsuspend: ");  //output:after return from sigsuspend:SIGINT,SIGUSR1;

 

    /* reset signal mask which unblocks SIGINT */
    if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)  //oldmask=SIGUSR1;
       err_sys("SIG_SETMASK error");

 

     /* and continue processing ... */
     pr_mask("oldmask in process :"); //output:oldmask in process :SIGUSR1;

 

   exit(0);


}

 static void sig_int(int signo)
{
    pr_mask("\nin sig_int: ");          //output: in sig_int:SIGINT;
}

 

 #gcc -g -o other_test_10.15_1 other_test_10.15_1.c
#./other_test_10.15_1

 

output:

in critical region: SIGINT SIGUSR1

 Ctrl+C(没有反应)

 

上面发出信号SIGINT没有反应的原因是,存在这一句 if (sigsuspend(&newmask)!= -1)      //newmask=SIGINT  它将信号SIGINT挂断了,所以按下Crtl+C键则没有反应,要理解好sigsuspend的意思!!

 

小结:

sigsuspend的整个原子操作过程为:
(1) 设置新的mask阻塞当前进程;
(2) 收到信号,调用该进程设置的信号处理函数;
(3) 待信号处理函数返回后,恢复原先mask;
(4) sigsuspend返回。