工作中使用案例:

struct sigaction act;
act.sa_sigaction = handleSignal;
act.sa_flags = SA_SIGINFO;
sigemptyset(&act.sa_mask);
sigaction(SIGTERM,&act,NULL);

转linux下的struct sigaction

 
 

Linux中信号相关的一个结构体struct sigaction主要在sigaction信号安装和sigqueue信号发送时会用到
该结构位于/usr/include/bits/sigaction.h
在里面可以找到该结构的描述

/* Structure describing the action to be taken when a signal arrives.     */
struct sigaction
     {
       /* Signal handler.     */

#ifdef __USE_POSIX199309
       union   
         {
       /* Used if SA_SIGINFO is not set.     */
       __sighandler_t sa_handler;
       /* Used if SA_SIGINFO is set.     */
       void (*sa_sigaction) (int, siginfo_t *, void *);
         }
       __sigaction_handler;
# define sa_handler __sigaction_handler.sa_handler
# define sa_sigaction      __sigaction_handler.sa_sigaction
#else
       __sighandler_t sa_handler;
#endif

/* Additional set of signals to be blocked.     */
       __sigset_t sa_mask;

/* Special flags.     */
       int sa_flags;

/* Restore handler.     */
       void (*sa_restorer) (void);
     };

在网上查了一些书料这个结构大概是这样的
其中,sa_restorer,已过时,POSIX不支持它,不应再被使用。

1、联合数据结构中的两个元素_sa_handler以及*_sa_sigaction指定信号关联函数,即用户指定的信号处理函数。除了可以是用户自定义的处理函数外,还可以为SIG_DFL(采用缺省的处理方式),也可以为SIG_IGN(忽略信号)。

2、由_sa_handler指定的处理函数只有一个参数,即信号值,所以信号不能传递除信号值之外的任何信息;由_sa_sigaction是指定的信号处理函数带有三个参数,是为实时信号而设的(当然同样支持非实时信号),它指定一个3参数信号处理函数。第一个参数为信号值,第三个参数没有使用(posix没有规范使用该参数的标准),第二个参数是指向siginfo_t结构的指针,结构中包含信号携带的数据值,参数所指向的结构如下:

在/usr/include/bits/siginfo.h中是这样定义的
是不是太复杂了,在网上有一个简洁版我搬过来用一下

siginfo_t {
                     int         si_signo;     /*信号值,对所有信号有意义*/
                     int         si_errno;     /* errno值,对所有信号有意义*/
                     int         si_code;      /*信号产生的原因,对所有信号有意义*/
union{      /*联合数据结构,不同成员适应不同信号*/
//确保分配足够大的存储空间
int _pad[SI_PAD_SIZE];
//对SIGKILL有意义的结构
struct{
...
     }...
... ...
... ...
//对SIGILL, SIGFPE, SIGSEGV, SIGBUS有意义的结构
         struct{
...
     }...
... ...
     }
}
<!--[if !supportLineBreakNewLine]-->
<!--[endif]-->

3、sa_mask指定在信号处理程序执行过程中,哪些信号应当被阻塞。缺省情况下当前信号本身被阻塞,防止信号的嵌套发送,除非指定SA_NODEFER或者SA_NOMASK标志位。

注:请注意sa_mask指定的信号阻塞的前提条件,是在由sigaction()安装信号的处理函数执行过程中由sa_mask指定的信号才被阻塞。

4、sa_flags中包含了许多标志位,包括刚刚提到的SA_NODEFER及SA_NOMASK标志位。另一个比较重要的标志位是SA_SIGINFO,当设定了该标志位时,表示信号附带的参数可以被传递到信号处理函数中,因此,应该为sigaction结构中的sa_sigaction指定处理函数,而不应该为sa_handler指定信号处理函数,否则,设置该标志变得毫无意义。即使为sa_sigaction指定了信号处理函数,如果不设置SA_SIGINFO,信号处理函数同样不能得到信号传递过来的数据,在信号处理函数中对这些信息的访问都将导致段错误(Segmentation fault)。

注:很多文献在阐述该标志位时都认为,如果设置了该标志位,就必须定义三参数信号处理函数。实际不是这样的,验证方法很简单:自己实现一个单一参数信号处理函数,并在程序中设置该标志位,可以察看程序的运行结果。实际上,可以把该标志位看成信号是否传递参数的开关,如果设置该位,则传递参数;否则,不传递参数。

结构说的也差不多了,其实在我看到这些东西的时候给弄晕了好几回,简单的说几句就是
如果要在某信号产生时触发某些动作我们就可以安装信号

signal用于安装不可靠信号     linux现在是用sigaction实现的
sigaction用于安装可靠信号当然他也可以安装不可靠信号并且可以附带更多的信息

signal安装信号时只需传入2个参数一个是信号的值    一个是信号发生时触发的函数,该函数接受一个整数
sigaction安装时有3个参数第一个参数是信号的值,第二个是sigaction结构这个结构说明了信号发生时调用的函数和其它的一些信息,主要的成员是sa_handler指定的触发函数只带一个参数即信号的值这和signal调用没什么区别,sa_sigaction指定的触发函数带有3个参数第一个参数是信号的值,第二个参数是包函附加信息的结构siginfo,第三个参数为空如果要传递附加信息给触发函数那么必须将传给sigaction的第二个参数sigaction结构的sa_flag设为SA_SIGINFO

上面说了那么多结构体和复杂的很的siginfo,其实siginfo我们在实际应用中并不需要去初始化他或者做什么,只是在信号触发时我们可以从这个结构体中提取一些信息。

sigaction函数原型:int sigaction(int signo,const struct sigaction *restrict act,struct sigaction *restrict oact);

//第一个参数为信号编号,第二个是sigaction结构体,第三个一般为NULL。

示例:

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>

static void sig_usr(int signum)
{
    if(signum == SIGUSR1)
    {
        printf("SIGUSR1 received\n");
    }
    else if(signum == SIGUSR2)
    {
        printf("SIGUSR2 received\n");
    }
    else
    {
        printf("signal %d received\n", signum);
    }
}

int main(void)
{
    char buf[512];
    int  n;
    struct sigaction sa_usr;
    sa_usr.sa_flags = 0;
    sa_usr.sa_handler = sig_usr;   //信号处理函数
    
    sigaction(SIGUSR1, &sa_usr, NULL);
    sigaction(SIGUSR2, &sa_usr, NULL);
    
    printf("My PID is %d\n", getpid());
    
    while(1)
    {
        if((n = read(STDIN_FILENO, buf, 511)) == -1)
        {
            if(errno == EINTR)
            {
                printf("read is interrupted by signal\n");
            }
        }
        else
        {
            buf[n] = '\0';
            printf("%d bytes read: %s\n", n, buf);
        }
    }
    
    return 0;
}

linux下的struct sigaction的更多相关文章

  1. Windows 和 Linux下使用socket下载网页页面内容(可设置接收/发送超时)的代码

    主要难点在于设置recv()与send()的超时时间,具体要注意的事项,请看代码注释部分,下面是代码: #include <stdio.h> #include <sys/types. ...

  2. linux下网络程序遭遇SIGPIPE的解决(转)

    http://blog.chinaunix.net/uid-20135786-id-3409085.html 问题描述: 我的一个服务器程序, 在Windows下运行正常. 但当在Linux(cent ...

  3. Linux下进程的同步相互排斥实例——生产者消费者

    linux下的同步和相互排斥 Linux sync_mutex 看的更舒服点的版本号= = https://github.com/Svtter/MyBlog/blob/master/Linux/pth ...

  4. Linux下多任务间通信和同步-信号

    Linux下多任务间通信和同步-信号 嵌入式开发交流群280352802,欢迎加入! 1.概述 信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式.信号可以直接进行用户空间进程和内核进程之间的 ...

  5. Linux下的定时器

    以下摘自linux下的man文件:(man  getitimer) #include  <sys/time.h> int  getitimer(int which,  struct iti ...

  6. Linux下套接字具体解释(三)----几种套接字I/O模型

    參考: 网络编程–IO模型演示样例 几种server端IO模型的简介及实现 背景知识 堵塞和非堵塞 对于一个套接字的 I/O通信,它会涉及到两个系统对象.一个是调用这个IO的进程或者线程,还有一个就是 ...

  7. [置顶] 简单解析linux下进程通信方法

    linux下的进程通信手段基本上是从Unix平台上的进程通信手段继承而来的.而对Unix发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间 ...

  8. Linux 下的一个全新的性能测量和调式诊断工具 Systemtap, 第 2 部分: DTrace

    DTrace的原理本系列文章详细地介绍了一个 Linux 下的全新的调式.诊断和性能测量工具 Systemtap 和它所依赖的基础 kprobe 以及促使开发该工具的先驱 DTrace 并给出实际使用 ...

  9. 在Linux下用C语言实现短信收发

     本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lyserver/archive/2008/10/01/3007090.aspx 首先,我根据功能需要创建了几个头文件 ...

随机推荐

  1. log4j使用教程

    日志是应用软件中不可缺少的部分,Apache的开源项目 Log4j 是一个功能强大的日志组件,提供方便的日志记录. 在官网:https://logging.apache.org/ ,点击 进入后,可以 ...

  2. Maven in 5 Minutes(Windows)

    这是根据官网的例子写的入门例子:http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html 1)下载maven: ...

  3. 使用git管理代码的心得

    一.简易使用流程 首先下载安装git,点击Git Bash进入编辑界面,之后如下图进入目录并通过命令 git init 把这个目录变成git可以管理的仓库 接下来使用git add .命令将所有文件添 ...

  4. WCF学习(二)对控件简单了解以及4个文本控件的简介

    WPF基础控件 系统默认提供的基础控件: 文本控件介绍与用法 Label控件 label控件:一般用户描述性文字显示. 在Label控件使用时,一般给予用户提示.用法上没有什么很特殊的,label控件 ...

  5. Html-Css-li标签增加图片

    制作一个需要显示颜色的圆点. <style> .item1 ul{list-style:none} .item1 li{padding-left:20px;background:url(圆 ...

  6. 【codevs1044】导弹拦截问题与Dilworth定理

    题目描述 Description 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某 ...

  7. 【HDU 1445】Ride to School

    题 题意 骑自行车,等0时开始最早出发的人,一起出发,然后被别人超过时,就追上去,终点距离是4.5km,速度单位是km/s,求到达的时间(s). 分析 贪心,找0时开始最早到的即可. 代码 #incl ...

  8. CentOS下crontab执行java程序

    阿里云CentOS收不到邮件 在crontab里配置执行脚本,脚本用来执行java程序,死活不执行.单独执行脚本可以运行. 查看crontab的日志文件,/var/log/cron,发现没有收到cro ...

  9. 【poj3714】 Raid

    http://poj.org/problem?id=3714 (题目链接) 现在才搞平面最近点对..感觉有点尴尬 题意 给出平面上两组点,每组n个,求两组点之间最短距离 Solution1 平面最近点 ...

  10. POJ 2182 Lost Cows

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10996   Accepted: 7059 Description N (2 ...