sigaction函数的使用

sigaction函数的使用sigaction函数的功能是检查或修改与指定信号相关联的处理动作(可同时两种操作)。他是POSIX的信号接口,而signal()是标准C的信号接口(如果程序必须在非POSIX系统上运行,那么就应该使用这个接口)给信号signum设置新的信号处理函数act,同时保留该信号原有的信号处理函数oldactintsigaction(intsigno,conststruct

大家好,又见面了,我是你们的朋友全栈君。

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;

 

  }

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/141428.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • pycharm如何安装python环境_pycharm怎么安装「建议收藏」

    pycharm如何安装python环境_pycharm怎么安装「建议收藏」安装方法:1、安装配置好Python环境;2、从官网下载pycharm安装程序;3、直接双击下载好的exe文件,进入安装向导界面,按照指示一步步操作;4、点击Install进行安装,等待安装完成后,点击Finish结束安装即可。本教程操作环境:windows7系统、Python3.5.2版本、DellG3电脑。首先我们来安装python1、首先进入网站下载:点击打开链接(或自己输入网址http…

    2022年8月27日
  • 分布式计算概述_分布式计算与处理

    分布式计算概述_分布式计算与处理**分布式计算是当前计算机领域常见的名词,那么到底什么是分布式,什么又是分布式计算呢?今天和大家共同研究一下这个话题。**分布式计算的概念一个分布式系统是由若干通过网络互联的计算机组成的软硬件系统,且这些计算机互相配合以完成一个共同目标(往往这个共同目标称为“项目”)分布式计算的优缺点优点:1.超大规模2.虚拟化3.高可靠性4.通用性5.高伸缩性6.按需服务7….

    2022年10月24日
  • python 装饰器

    python 装饰器本文首先介绍了什么是闭包函数,然后从闭包函数引入到了函数装饰器、类装饰器,之后又说明了如果一个函数被多个装饰器同时修饰时它们的执行顺序是什么样的,最后介绍了避免装饰后原函数信息丢失的解决方案。

    2022年7月5日
  • python实现矩阵的转置_Python实现矩阵转置的方法分析

    python实现矩阵的转置_Python实现矩阵转置的方法分析本文实例讲述了Python实现矩阵转置的方法。分享给大家供大家参考,具体如下:前几天群里有同学提出了一个问题:手头现在有个列表,列表里面两个元素,比如[1,2],之后不断的添加新的列表,往原来相应位置添加。例如添加[3,4]使原列表扩充为[[1,3],[2,4]],再添加[5,6]扩充为[[1,3,5],[2,4,6]]等等。其实不动脑筋的话,用个二重循环很容易写出来:def…

    2022年5月6日
  • smartctl命令详解_cmp汇编语言

    smartctl命令详解_cmp汇编语言smartctl输出详解

    2022年10月8日
  • java setscale_java BigDecimal.setScale()的一些问题

    java setscale_java BigDecimal.setScale()的一些问题环境:Eclipse3.6jdk:1.6程序:packagecom.test.doubletest;importjava.math.BigDecimal;publicclassDoubleDataType{/***@paramargs*/publicstaticvoidmain(String[]args){Doubled_0=newDouble(0.00929…

    2022年10月20日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号