Sigaction

#include <signal.h>
int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);

功能:

sigaction函数用于改变进程接收到特定信号后的行为。

参数

第一个参数为信号的值,可以为除SIGKILL及SIGSTOP外的任何一个特定有效的信号(为这两个信号定义自己的处理函数,将导致信号安装错误)

第二个参数是指向结构sigaction的指针,在结构 sigaction的实例中,指定了对特定信号的处理,可以为空,进程会以缺省方式对信号处理

第三个参数oldact指向的对象用来保存原来对相应信号的处理,可指定oldact为NULL。

返回值:函数成功返回0,失败返回-1

sigaction结构体

第二个参数最为重要,其中包含了对指定信号的处理、信号所传递的信息、信号处理函数执行过程中应屏蔽掉哪些函数等等

struct sigaction {
//信号处理程序 不接受额外数据(比较过时)void (*sa_handler)(int);//信号处理程序能接受额外数据,和sigqueue配合使用(支持信号排队,信号传送其他信息),推荐使用void (*sa_sigaction)(int, siginfo_t *, void *);         sigset_t sa_mask;   //屏蔽int sa_flags;       //表示信号的行为:SA_SIGINFO表示能接受数据void (*sa_restorer)(void); //废弃不用了
};
//简单示例1: 用sigaction简单替换signal函数
void signalAction(int signo, siginfo_t *signalInfo, void *p)
{cout << "signal = " << signo << ", desc: " << strsignal(signo) << endl;
}int main()
{struct sigaction act;//注意:回调函数句柄sa_handler、sa_sigaction只能选其一!!!//act.sa_handler = sigHandler;act.sa_sigaction = signalAction;sigemptyset(&act.sa_mask);act.sa_flags = 0;if (sigaction(SIGINT,&act,NULL) == -1)err_exit("sigaction error");pause();
}
//简单实例2: 用sigaction模拟signal函数
sighandler_t mySignal(int signum, sighandler_t handler)
{struct sigaction act;struct sigaction oldAct;act.sa_handler = handler;sigemptyset(&act.sa_mask);act.sa_flags = 0;if (sigaction(signum, &act, &oldAct) == -1)return SIG_ERR;return oldAct.sa_handler;
}

sa_mask选项

sa_mask specifies a mask of signals which should be blocked/** 指定一个信号集的掩码, 在这个掩码中的信号将要阻塞**/      (i.e., added  to  the  signal mask of the thread in which the signal handler is invoked)

during execution of the signal handler.  In addition, the signal which triggered the handler will be blocked,

unless the SA_NODEFER flag is used.

/** 在执行handler 的时候, 如果此时进程收到了sa_mask所包含的信号, 则这些信号将不会被响应, 直到handler函数执行完毕

与sigprocmask不同是: sigprocmask 是指定该进程的信号屏蔽字-> 屏蔽该信号, 不会接收该信号, 而sa_mask则是接收了该信号, 但是不会相应该信号**/

//示例: 将sa_mask选项设置以后的效果
/** 在进程相应SIGINT信号时, 如果此时有SIGQUIT信号抵达, SIGQUIT信号也不会被响应, 直到SIGINT信号相应完成之后, 才会去相应SIGQUIT信号(如运行截图所示)**/
int main()
{struct sigaction act;act.sa_handler = sigHandler;sigemptyset(&act.sa_mask);// 添加下面一行后: 在响应SIGINT信号时, 是不会被中断的sigaddset(&act.sa_mask, SIGQUIT);act.sa_flags = 0;if (sigaction(SIGINT, &act, NULL) == -1)err_exit("sigaction error");while (true)pause();
}
void sigHandler(int signo)
{cout << "catch a signal, signo = " << signo << ", desc: " << strsignal(signo) << endl;sleep(10);
}

//运行截图

sa_flags: 详细信息

siginfo_t结构:

siginfo_t{int      si_signo;    /* Signal number */int      si_errno;    /* An errno value */int      si_code;     /* Signal code */int      si_trapno;   /* Trap number that causedhardware-generated signal(unused on most architectures) */pid_t    si_pid;      /* Sending process ID */uid_t    si_uid;      /* Real user ID of sending process */int      si_status;   /* Exit value or signal */clock_t  si_utime;    /* User time consumed */clock_t  si_stime;    /* System time consumed */sigval_t si_value;    /* Signal value */int      si_int;      /* POSIX.1b signal */void    *si_ptr;      /* POSIX.1b signal */int      si_overrun;  /* Timer overrun count; POSIX.1b timers */int      si_timerid;  /* Timer ID; POSIX.1b timers */void    *si_addr;     /* Memory location which caused fault */long     si_band;     /* Band event (was int inglibc 2.3.2 and earlier) */int      si_fd;       /* File descriptor */short    si_addr_lsb; /* Least significant bit of address(since Linux 2.6.32) */
}

sigqueue

#include <signal.h>
int sigqueue(pid_t pid, int sig, const union sigval value);

功能

sigqueue是新的发送信号系统调用,主要是针对实时信号提出的支持信号带有参数,与函数sigaction()配合使用。

和kill函数相比多了一个参数:const union sigval value(int kill(pid_t pid, int sig)),因此sigqueue()可以比kill()传递更多的信息,但sigqueue()只能向一个进程发送信号,而不能发送信号给一个进程组。

参数

参数1是指定接收信号的进程id,参数2确定即将发送的信号;

参数3是一个联合数据结构union sigval,指定了信号传递的参数,即通常所说的4字节值。

sigval联合体

typedef union sigval{int sival_int;void *sival_ptr;
} sigval_t;
//综合实验sigaction+sigqueue
void onSa_SignalAction(int signalNum, siginfo_t *signalInfo, void *p)
{cout << "signalNum = " << signalNum << endl;//int recValue = signalInfo -> si_value.sival_int;  同下int recValue = signalInfo -> si_int;cout << "recvValue = " << recValue << endl;
}int main()
{struct sigaction act;sigemptyset(&act.sa_mask);act.sa_flags = SA_SIGINFO;act.sa_sigaction = onSa_SignalAction;if (sigaction(SIGINT,&act,NULL) == -1)err_exit("sigaction error");pid_t pid = fork();if (pid == -1)err_exit("fork error");else if (pid == 0)  //In Child{/*typedef union sigval{int sival_int;void *sival_ptr;} sigval_t;*///union sigval signalValue; 同下sigval_t signalValue;signalValue.sival_int = 256;sleep(2);//给父进程发送SIGINT信号sigqueue(getppid(),SIGINT,signalValue);}pause();return 0;
}

Linux信号实践(4) --可靠信号相关推荐

  1. Linux信号实践(2) --信号分类

    信号分类 不可靠信号 Linux信号机制基本上是从UNIX系统中继承过来的.早期UNIX系统中的信号机制比较简单和原始,后来在实践中暴露出一些问题,它的主要问题是: 1.进程每次处理信号后,就将对信号 ...

  2. 可靠信号与不可靠信号

    来自:http://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index1.html 一.信号及信号来源 信号本质 信号是软件中断,是在软件层次上 ...

  3. 深入理解Linux进程间通信(IPC)-- 信号signal

    2. 信号(上) 2.1. 信号及信号来源 2.1.1 信号本质 信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的.信号是异步的,一个进程不 ...

  4. 【B站视频笔记】linux 进程间通信(ipc)信号(软中断信号)signal库函数、可靠信号和不可靠信号、信号集sigprocmask(信号掩码、信号递达Delivery、信号未决Pending)

    [视频教程]Linux信号详解(可靠信号.不可靠信号.阻塞信号.信号处理函数) [博文]Linux信号 文章目录 背景 课程笔记 一.如何让程序在后台运行 1.加"&"符号 ...

  5. 如何验证Linux Signal可靠信号与不可靠信号

    前面章节已经<Linux下的Signal信号处理及详解>说了,Linux 下的信号分为可靠信号和不可靠信号,或称为实时信号和非实时信号,信号是从1开始编号的,不存在0号信号.0信号用来测试 ...

  6. Linux信号实践(3) --信号内核表示

    信号在内核中的表示 执行信号的处理动作称为信号递达(Delivery),信号从产生到递达之间的状态,称为信号未决(Pending).进程可以选择阻塞(Block)某个信号.被阻塞的信号产生时将保持在未 ...

  7. Linux信号实践(1) --Linux信号编程概述

    中断 中断是系统对于异步事件的响应, 进程执行代码的过程中可以随时被打断,然后去执行异常处理程序; 计算机系统的中断场景:中断源发出中断信号 -> CPU判断中断是否屏蔽屏蔽以及保护现场 -&g ...

  8. 不可靠的信号、可靠信号

    一.不可靠信号 lnux信号机制基本上是从UNIX系统中继承过来的.早期UNIX系统中的信号机制比较简单和原始,后来在实践中暴露一些问题,它的主要问题是: 1. 进程每次处理信号后,就将对信号的响应设 ...

  9. [Linux学习笔记] 浅谈信号(文章含不少学习资源)

    百金买骏马,千金买美人,万金买爵禄,何处买青春? 目录 信号的概念 信号的种类: kill -l 命令可以查看信号列表 man 7 signal 查看信号详细内容 信号的产生 补充知识 Core Du ...

最新文章

  1. [高数][高昆轮][高等数学上][第二章-导数与微分]01.导数的定义
  2. 从短句到长文,计算机如何学习阅读理解
  3. 一秒钟世界上会发生多少事_1秒钟世界上会发生多少事?答案超乎你的想象……...
  4. Linux的RPM管理
  5. python3 xpath_Python3使用Xpath解析网易云音乐歌手页面
  6. eclipse build path 以及 clean(转)
  7. 洪嘉振 计算多体系统动力学pdf_如何在多体动力学模型中评估齿轮啮合刚度
  8. Mac下好用的取色器 Sip
  9. LeetCode 188. 买卖股票的最佳时机 IV(动态规划)
  10. mysql bitmap index_[MySQL] mysql中bitmap的简单运用
  11. Jquery学习总结(7)——JQuery常用的10个方法总结
  12. Linux之cd命令
  13. Unix/Linux的内存映射
  14. 【Ubuntu】Ubuntu16.04安装火狐浏览器中国版
  15. linux获取utc时间函数,Linux下的时间函数
  16. Win10 安装虚拟机ROS
  17. Java动态代理的原理
  18. Dubbo系列之微服务框架整合教程
  19. 20轮廓-hu不变矩的测试程序
  20. jsp+servlet的增删改查页面

热门文章

  1. 计算机网络之数据链路层:17、PPP协议、HDLC协议
  2. (计算机组成原理)第五章中央处理器-第四节3:微指令的设计
  3. Clumsy网络模拟工具
  4. 处理大并发之四 libevent demo详细分析(对比epoll)
  5. 利用异步I/O复制文件及详解
  6. unubtu16.04解决etc文件误改导致无法使用sudo等指令问题
  7. python 文件指针及文件覆盖
  8. NOIP 2015 提高组 Day2
  9. [bzoj1191][HNOI2006]超级英雄Hero
  10. Android深度探索(卷1)HAL与驱动开发 心得体会 第十章 嵌入式Linux的调用技术