sigsuspend()函数

  在学习sigsuspend()函数时存在一些迷惑,并不太理解书上所叙述的内容。最终,结合网上资源对该函数慢慢有了一点理解,记录下来,以备以后补充。

  在《UNIX环境高级编程》中该函数的提出是在解除信号屏蔽(这里以SIGINT为例)时,信号立即发生,没有等待到pause函数执行的情况下。

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

if(sigprocmask(SIG_BLOCK,&newmask,&oldmask)<0){
err_sys("SIG_BLOCK error");
}
...
if(sigprocmask(SIG_SETMASK,&oldmask,NULL)<0){
err_sys("SIG_SETMASK error");
}
//------------>此处正好接受并处理SIGINT信号(与内核如何实现信号有关)
pause();

       这样如果后面不再收到信号,那么pause函数就一直挂起。

  

#include <signal.h>
int sigsuspend(const sigset_t *sigmask);

        返回值:-1,并将error设置为EINTR(与pause函数返回值相同)

  进程的信号屏蔽字设置为sigmask指向的值。在捕捉到一个信号或发生了一个会终止该进程的信号前,该进程被挂起(像pause函数一样)。

  等到捕捉到信号,并从该信号的处理函数返回,sigsuspend函数才返回,并将该进程的信号屏蔽字设置为调用sigsuspend前。

  sigsuspend()函数相当于将信号的产生与pause函数同时进行,接收到信号后会停止挂起。(不再会出现先产生信号后再调用pause的情况)

 

  以下是在实现sleep函数中的应用:

  

//没有使用sigsuspend()
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
void del_func()
{
}

unsigned int mySleep(unsigned int seconds){
int ret;
struct sigaction act,oldact;

act.sa_handler = del_func;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);

ret = sigaction(SIGALRM,&act,&oldact);
if(ret == -1){
perror("sigaction error");
exit(-1);
}

alarm(seconds);
//----------------------------------->如果此处该进程被cpu挂起,当定时结束发送SIGALRM信号,后面的pause不能接收到(概率极小,但是不可以不考虑)
ret = pause();
if(ret==-1&&errno == EINTR){
printf("pause success\n");
}

ret = alarm(0);
sigaction(SIGALRM,&oldact,NULL);

return ret;
}

int main()
{

while(1){
printf("======\n");
mySleep(3);
}
return 0;
}

=========================================================

//使用sigsuspend()函数
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
void del_func()
{
}

unsigned int mySleep(unsigned int seconds){
int ret;
struct sigaction act,oldact;
sigset_t newmask,oldmask,waitmask;
unsigned int unslept;

act.sa_handler = del_func;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);

ret = sigaction(SIGALRM,&act,&oldact);
if(ret == -1){
perror("sigaction error");
exit(-1);
}

sigemptyset(&newmask);
sigaddset(&newmask,SIGINT);
sigprocmask(SIG_BLOCK,&newmask,&oldmask);

alarm(seconds);

waitmask = oldmask;

sigsuspend(&waitmask);

unslept = alarm(0);
sigaction(SIGALRM,&oldact,NULL);

sigprocmask(SIG_SETMASK,&oldmask,NULL);

return unslept;
}
int main()
{

while(1){
printf("======\n");
mySleep(3);
}


return 0;
}

 

posted on 2018-12-11 18:53  dogpi  阅读(891)  评论(0编辑  收藏  举报

导航