您的位置:首页 > 其它

文章标题

2015-10-23 13:57 204 查看
sigaction函数的功能是检查或修改与指定信号相关联的处理动作(可同时两种操作)。

他是POSIX的信号接口,而signal()是标准C的信号接口(如果程序必须在非POSIX系统上运行,那么就应该使用这个接口)

给信号signum设置新的信号处理函数act, 同时保留该信号原有的信号处理函数oldact

int sigaction(int signo,const struct sigaction *restrict act,

struct sigaction *restrict oact);

结构sigaction定义如下:

struct sigaction{

void (*sa_handler)(int);

sigset_t sa_mask;

int sa_flag;

void (sa_sigaction)(int,siginfo_t ,void *);

};

sa_handler字段包含一个信号捕捉函数的地址

sa_mask字段说明了一个信号集,在调用该信号捕捉函数之前,这一信号集要加进进程的信号屏蔽字中。仅当从信号捕捉函数返回时再将进程的信号屏蔽字复位为原先值。

sa_flag是一个选项,主要理解两个

SA_INTERRUPT 由此信号中断的系统调用不会自动重启

SA_RESTART 由此信号中断的系统调用会自动重启

SA_SIGINFO 提供附加信息,一个指向siginfo结构的指针以及一个指向进程上下文标识符的指针

最后一个参数是一个替代的信号处理程序,当设置SA_SIGINFO时才会用他。

例子:

include

include

include

void show_handler(int sig)

{

printf(“I got signal %d\n”, sig);

int i;

for(i = 0; i < 5; i++) {

printf(“i = %d\n”, i);

sleep(1);

}

}

int main(void)

{

int i = 0;

struct sigaction act, oldact;

act.sa_handler = show_handler;

sigaddset(&act.sa_mask, SIGQUIT); //见注(1)

act.sa_flags = SA_RESETHAND | SA_NODEFER; //见注(2)

//act.sa_flags = 0; //见注(3)

sigaction(SIGINT, &act, &oldact);
while(1) {
sleep(1);
printf("sleeping %d\n", i);
i++;
}


}

注:

(1) 如果在信号SIGINT(Ctrl + c)的信号处理函数show_handler执行过程中,本进程收到信号SIGQUIT(Crt+),将阻塞该信号,直到show_handler执行结束才会处理信号SIGQUIT。

(2) SA_NODEFER 一般情况下, 当信号处理函数运行时,内核将阻塞<该给定信号 – SIGINT>。但是如果设置了SA_NODEFER标记, 那么在该信号处理函数运行时,内核将不会阻塞该信号。 SA_NODEFER是这个标记的正式的POSIX名字(还有一个名字SA_NOMASK,为了软件的可移植性,一般不用这个名字)

SA_RESETHAND 当调用信号处理函数时,将信号的处理函数重置为缺省值。 SA_RESETHAND是这个标记的正式的POSIX名字(还有一个名字SA_ONESHOT,为了软件的可移植性,一般不用这个名字)

(3) 如果不需要重置该给定信号的处理函数为缺省值;并且不需要阻塞该给定信号(无须设置sa_flags标志),那么必须将sa_flags清零,否则运行将会产生段错误。但是sa_flags清零后可能会造成信号丢失!

sigaction

  sigaction(查询或设置信号处理方式)

  相关函数 signal,sigprocmask,sigpending,sigsuspend, sigemptyset

  表头文件 #include

  定义函数 int sigaction(int signum,const struct sigaction *act ,struct sigaction *oldact);

  函数说明 sigaction()会依参数signum指定的信号编号来设置该信号的处理函数。参数signum可以指定SIGKILL和SIGSTOP以外的所有信号。

  如参数结构sigaction定义如下

  struct sigaction {

  union{

  __sighandler_t sa_handler;

  void (_sa_sigaction)(int,struct siginfo , void *);

  }_u

  sigset_t sa_mask;

  unsigned long sa_flags;

  void (*sa_restorer)(void);

  }

  信号处理函数可以采用void (sa_handler)(int)或void (*sa_sigaction)(int, siginfo_t , void )。到底采用哪个要看sa_flags中是否设置了SA_SIGINFO位,如果设置了就采用void (*sa_sigaction)(int, siginfo_t , void *),此时可以向处理函数发送附加信息;默认情况下采用void (*sa_handler)(int),此时只能向处理函数发送信号的数值。

  sa_handler此参数和signal()的参数handler相同,代表新的信号处理函数,其他意义请参考signal()。

  sa_mask 用来设置在处理该信号时暂时将sa_mask 指定的信号搁置。

  sa_restorer 此参数没有使用。

  sa_flags 用来设置信号处理的其他相关操作,下列的数值可用。 

  sa_falgs还可以设置其他标志:

  SA_RESETHAND:当调用信号处理函数时,将信号的处理函数重置为缺省值SIG_DFL

  ··SA_RESTART:如果信号中断了进程的某个系统调用,则系统自动启动该系统调用

  SA_NODEFER :一般情况下, 当信号处理函数运行时,内核将阻塞该给定信号。但是如果设置了 SA_NODEFER标记, 那么在该信号处理函数运行时,内核将不会阻塞该信号

  sigaction

sigaction()

示例

  #include

  static void int_hander(int s)

  {

  printf(“Catch a signal sigint\n”);

  }

  int

  main(void)

  {

  int i;

  struct sigaction act, oact;

  act. sa_handler = int_hander;

  sigemptyset(&act. sa_mask); //清空此信号集

  act. sa_flags = 0;

  sigaction(SIGINT, &act, &oact);

  //signal(SIGINT, SIG_IGN);

  while(1){

  for(i=0; i<5; i++){

  write(1, “.”, 1);

  sleep(1);

  }

  write(1, “\n”, 1);

  }

  sigaction(SIGINT, &oact, NULL); //恢复成原始状态

  return 0;

  }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: