Chinaunix首页 | 论坛 | 博客
  • 博客访问: 558845
  • 博文数量: 142
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1452
  • 用 户 组: 普通用户
  • 注册时间: 2013-09-12 16:28
文章分类

全部博文(142)

文章存档

2016年(10)

2015年(60)

2014年(72)

我的朋友

分类: LINUX

2016-06-15 14:43:34

sigaction函数的功能是检查或修改与指定信号相关联的动作(或同时执行这两种操作)
#include
int sigaction(int signo, const struct sigaction *act, struct sigaction *oact);
返回值: 若成功则返回0,出错则返回-1

参数signo是要检测或修改器具体动作的信号编号。如果act指针为非空,则要修改其动作。
如果oact不为空,则系统经由oact指针返回该信号的上一个动作。

struct sigaction {
void (*sa_handler)(int);    /*信号处理函数*/
sigset_t sa_mask;           /*additional signals to block, sa_mask字段是一个信号集,在调用该信号处理函数之前,这一信号集要加到进程的信号屏蔽字中。
                             仅当从信号处理函数返回时再讲进程的信号屏蔽字复位为原先值。这样,在调用信号处理程序时就能阻塞某些信号。*/
int sa_flags;               /*指定对信号处理的各个选项,如SA_RESTART,此信号中断的系统调用会自动重启动*/
void (*sa_sigaction)(int, siginfo_t *,void *);
};


一旦对给定的信号设置了一个动作,那么在调用sigaction显示地改变它之前,该设置就一直有效。

用sigaction实现的signal函数

点击(此处)折叠或打开

  1. void (*signal(int signo,void(*func)(int)))(int)
  2. {
  3.     struct sigaction act, oact;
  4.     
  5.     setsigempty(&act.sa_mask);
  6.     act.sa_handler = func;
  7.     act.sa_flags = 0;
  8.     /*对除SIGALRM以外的所有信号,我们都有意尝试设置SA_RESTART标志,于是这些信号中断的系统调用都能重启动。*/
  9.     if (signo == SIGALARM) {
  10.     #ifdef SA_INTERRUPT
  11.         act.sa_flags |= SA_INTERRUPT;
  12.     #endif
  13.     } else {
  14.     #ifdef SA_RESTART
  15.         act.sa_flags |= SA_RESTART;
  16.     #endif
  17.     }
  18.     if(sigaction(signo,&act,&oact) < 0) {
  19.         return SIGERR;
  20.     }
  21.     return oact.sa_handler;
  22. }
用sigaction实现的signal函数(目前linux系统里面默认的signal函数已经是sigaction实现的版本了)
 在信号处理处理函数被调用时,操作系统建立的新信号屏蔽字包含正在被递送的信号
因此保证了在处理一个给定的信号时,如果这种信号再次发生,那么它会被阻塞到对前一个信号的处理结束为止.
 同一种信号多次发生,通常并不讲它们排队,所以如果在某种信号被阻塞时它发生了五次,
那么对这种信号解除阻塞后,其信号处理函数通常只会被调用一次。
举例:

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <signal.h>
  4. #include <unistd.h>
  5. static void sig_int(int);

  6. int main(void)
  7. {
  8.     if(signal(SIGINT,sig_int) == SIG_ERR)
  9.         perror("can't catch SIGINT\n");

  10.     for(;;)
  11.         pause;
  12. }

  13. void sig_int(int signo)
  14. {
  15.     printf("received SIGINT\n");
  16.     sleep(10);
  17.     printf("after sleep 10s\n");
  18. }
  19. [root@localhost signal]#
编译运行:

点击(此处)折叠或打开

  1. [root@localhost signal]# gcc -g signal.c -o signal
  2. [root@localhost signal]# ./signal
  3. ^Creceived SIGINT            -----输入一个CTRL+C,打印出received SIGINT
  4. ^C^C^C^C^C                   -----持续输入5次CTRL+C,由于在上面一次CTRL+C的信号处理函数中,这5次CTRL+C被阻塞


  5. /*空白处为输入回车*/



  6. after sleep 10s            ----过了10s,第一次的CTRL+C信号处理函数退出
  7. received SIGINT            ----直接就输出了received SIGINT, 只是一次而不是5次。
  8. after sleep 10s            ----过了10s,信号处理函数再次退出





阅读(1379) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~