信号的总结

来源:互联网 发布:柳州博腾网络 编辑:程序博客网 时间:2024/06/10 06:01

一、signal 是不可靠的:

在Ubuntu10.04,Kernel 2.6.23上,其设置的信号函数仅仅触发一次,触发完之后恢复为默认动作,但是sigaction函数设置之后一直有效;

如下代码(摘自UNIX环境高级编程)当使用signal时,仅仅触发一次sig_int,再次发送中断信号执行默认操作:程序被终止;

但是用sigaction设置,一直会触发sig_int函数;


#include "../apue.h"

volatile sig_atomic_t quitflag;
static void sig_int(int signo)
{
 if(signo == SIGINT)
  printf("\n interrupt\n");
 else if(signo == SIGQUIT)
  quitflag = 1;
}

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

#if 0
 if(signal(SIGINT, sig_int) == SIG_ERR)
  err_sys(" signal(SIGINT) error");
 if(signal(SIGQUIT, sig_int) == SIG_ERR)
  err_sys("signal(SIGQUIT) error");
#endif
 struct sigaction act;
 act.sa_handler = sig_int;
 sigemptyset(&act.sa_mask);
 act.sa_flags = 0;
 if(sigaction(SIGINT, &act, NULL) < 0)
  err_sys("sigaction SIGINT error");
 if(sigaction(SIGQUIT, &act, NULL) < 0)
  err_sys("sigaction SIGINT error");


 sigemptyset(&zeromask);
 sigemptyset(&newmask);
 sigaddset(&newmask, SIGQUIT);

 // Block SIGQUIT and save current signal mask
 if(sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
  err_sys("SIG_BLOCK error");


 while(quitflag==0)
 {
  sigsuspend(&zeromask);
 }
 quitflag = 0;

 // reset signal mask
 if(sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
  err_sys("failed to set mask");

 exit(0);
}


二、sigsuspend(const sigset_t *sigmask)的理解:

该函数将信号屏蔽字设置为由sigmask指向的值,//就是说新的信号屏蔽字为sigmask,如果你之前调用sigprocmask设置了信号屏蔽字,那么这个设置会失效,当sigsuspend返回时,才能恢复为sigprocmask设置的值;

在捕捉到一个信号或发生了一个会终止该进程的信号之前,该进程被挂起。

如果捕捉到一个信号且从处理程序返回,则sigsuspend返回,并且将该进程的信号屏蔽字设置为调用sigsuspend之前的值;//此时sigsuspend设置的sigmask失效,之前的屏蔽字恢复;




原文:http://blog.csdn.net/wei_gw2012/article/details/78389286



原创粉丝点击