Chinaunix首页 | 论坛 | 博客
  • 博客访问: 292731
  • 博文数量: 63
  • 博客积分: 814
  • 博客等级: 军士长
  • 技术积分: 700
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-09 15:46
文章分类

全部博文(63)

文章存档

2017年(1)

2016年(4)

2015年(13)

2014年(9)

2012年(3)

2011年(33)

分类: LINUX

2011-05-17 14:21:27

由来:
   更改信号屏蔽字可以阻塞或解除阻塞所选择的信号,使用这种技术可以保护不希望由信号中断的代码临界区。
实现:
sigset_t newmask,oldmask;

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

if(sigprocmask(SIG_BLOCK,&newmask,&oldmask)<0)
   printf("error");

/*critical region of code*/

if(sigprocmask(SIG_SETMASK,&oldmask,NULL)<0)           ///----start
   printf("error");

pause();    /*wait for signal to occur*/                               ///----end

/*continue processing*/

在critical region内发生的信号(newmask设置的)暂不作处理,sigprocmask(SIG_SETMASK..),返回后会对newmask设置的信号进行处理。

   例子说白了就是程序运行到
critical region段时,收到的SIGINT信号将推迟sigprocmask(SIG_SETMASK..),返回。

pause(); 在等待信号的发生,但此处会发生问题,如果SIGINT,是在
sigprocmask(SIG_SETMASK..)和pause()之间发生,进入pause()后将丢失此信号。
   
   为了纠正此问题,需要在一个原子操作中实现恢复信号屏蔽字,然后使进程睡眠,这种功能由sigsuspend函数提供因此有了sigsuspend函数。
(start end 那段变成原子)

sigsuspend(const sigset_t *sigmask)
作用:

1:进程的信号屏蔽字设置为sigmask指向的值,
2:在捕捉到一个信号或发生了一个会终止该进程的信号之前,该进程也被挂起。
3:如果捕捉到一个信号而且从该信号处理程序返回,则sigsuspend返回,并且信号屏蔽字设置为调用sigsuspend 之前的值。


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

if(signal(SIGINT,sig_int)==SIG_ERR)
   printf("error");
sigemptyset(&zeromask);
sigemptyset(&newmask);
sigaddset(&newmask,SIGINT);

if(sigprocmask(SIG_BLOCK,&newmask,&oldmask)<0)
   printf("error");

/*critical region of code*/

if(sigsuspend(&zeromask)!=-1)   //在此代入三个功能点就可理解。
  printf("error");

if(sigprocmask(SIG_SETMASK,&oldmask,NULL)<0)
   printf("error");

exit(0);
}
阅读(958) | 评论(0) | 转发(0) |
0

上一篇:tcp 超时与重传

下一篇:nginx 进程重启机制

给主人留下些什么吧!~~