Linux -- 信号编程
进程捕捉到信号对其进行处理时,进程正在执行的正常序列就被信号处理程序临时中断,它首先执行该信号处理程序中的指令。如果从信号处理程序返回(例如没有调用exit或longjmp),则继续执行在捕捉到信号时进程正在执行的正常指令序列。
1. 在信号处理程序中,我们要保证调用”异步信号安全”的函数,即可重入的函数
不可重入的函数大多(a)已知它们使用静态数据结构。(b)它们调用malloc或free(c)它们是标准I/O函数
2. 由于每个线程只有一个errno变量,所以信号处理程序可能会修改其原先值。因此,所有信号处理程序应当在函数的起始保存errno,结尾恢复errno
3. 每个进程都有一个信号屏蔽字(signal mask),它规定了当前要阻塞传递送到该进程的信号集
信号集signal set
int sigemptyset(sigset_t *set); //初始化由set指向的信号集,清除其中所有信号 int sigfillset(sigset_t *set); //初始化由set指向的信号集,使其包括所有信号
所有应用程序在使用信号集前,要对该信号集调用sigemptyset或sigfillset一次。
信号集初始化之后,可在该信号中增删特定的信号。
int sigaddset(sigset_t *set,int signo) int sigdelset(sigset_t *set,int signo)
进程的信号屏蔽字
int sigprocmask(int how,const sigset_t *restrict set, const sigset_t *restrict oset)
Oset若是非空指针,那么进程的当前信号屏蔽字通过oset返回
How的三种取值决定了如何修改当前信号屏蔽字:
SIG_BLOCK : 向当前信号屏蔽字中添加参数set包含的信号
SIG_UNBLOCK : 把当前信号屏蔽字中参数set包含的信号删去
SIG_SETMASK : 把参数set设为进程的信号屏蔽字。
请注意,sigprocmask仅为单线程进程定义的。处理多线程进程中信号的屏蔽使用另一个函数
执行信号的处理程序称为信号递达,信号从产生到递达之间的状态称为信号未决。被阻塞的信号将保持在未决状态,直到进程解决对此信号的阻塞。
int sigpending(sigset_t *set)
Set返回当前的未决信号
信号处理的范式
static int pipefd[]; int signal_module_init() {
struct sigaction act; //信号处理程序指定为sig_handler
act.sa_handler = sig_handler; //在进入信号处理程序前,把act.sa_mask信号集加到进程的信号屏蔽字中。调用sigfillset把所有信号加入这个信号集。这表示当进入信号处理程序后,阻塞一切信号
sigfillset(&act.sa_mask) if( > sigaction(SIGINT,&act,) ||
> sigaction(SIGCHLD,&act,) ||
...... ) {
write_log("failed to init signal:sigaction()");
return -;
}
return signal_pipe_init();
} static int signal_pipe_init()
{
if( < pipe(pipefd,O_CLOEXEC|O_NONBLOCK) ){
write_log("failed to init pipe");
return -;
}
return ;
} static void sig_handler(int signo)
{
//定义一个数组,将你注册的每个信号的signo映射成一个唯一的字符
static const char sig_chars[NSIG+] = {
[SIGINT] = 'I',
[SIGCHLD] = 'C',
.....
}; char s;
int saved_errno; //保存当前的errno。每个线程仅有一个errno变量,不应让信号处理程序中的errno影响正常流程中的errno。因此我们需要在信号处理程序的起始存储errno,在末尾恢复errno
saved_errno = errno;
s = sig_chars[signo];
write(pipefd[],&s,sizeof(s));
errno = saved_errno; } //然后在Reactor中监听pipefd[0]. 其回调函数如下:
void got_signal(ev)
{
int res,ret;
char c;
int fd = ev->fd;
for(;;){
//fd是非阻塞的
do {
res = read(fd,&c,);
} while(res == - && errno == EINTR); //pipe中没有可读数据
if(res <= ){
break;
} switch(c){
case 'I':
dosomething1();
break;
case 'C':
dosomething2();
break;
......
}
}
return;
}
Linux -- 信号编程的更多相关文章
- Linux信号实践(1) --Linux信号编程概述
中断 中断是系统对于异步事件的响应, 进程执行代码的过程中可以随时被打断,然后去执行异常处理程序; 计算机系统的中断场景:中断源发出中断信号 -> CPU判断中断是否屏蔽屏蔽以及保护现场 -&g ...
- linux系统编程之信号(七)
今天继续学习信号,主要是学习关于时间和定时器相关的函数的使用,关于这个实际上有很多内容,这里先简要进行说明,等之后再慢慢进行相关深入,也主要是为接下来要做的一个综合linux系统编程的例子做准备,好了 ...
- (50)LINUX应用编程和网络编程之五 Linux信号(进程间通信)
信号实现进程间的通信 3.5.1.什么是信号 ...
- Linux 系统编程 学习:03-进程间通信1:Unix IPC(2)信号
Linux 系统编程 学习:03-进程间通信1:Unix IPC(2)信号 背景 上一讲我们介绍了Unix IPC中的2种管道. 回顾一下上一讲的介绍,IPC的方式通常有: Unix IPC包括:管道 ...
- Linux 网络编程的5种IO模型:信号驱动IO模型
Linux 网络编程的5种IO模型:信号驱动IO模型 背景 上一讲 Linux 网络编程的5种IO模型:多路复用(select/poll/epoll) 我们讲解了多路复用等方面的知识,以及有关例程. ...
- Linux系统编程(20)——信号基本概念
信号及信号来源 信号是在软件层次上对中断机制的一种模拟,在原理上,一个进程收到一个信号与处理器收到一个中断请求可以说是一样的.信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知 ...
- linux系统编程之信号(一):中断与信号
一,什么是中断? 1.中断的基本概念 中断是指计算机在执行期间,系统内发生任何非寻常的或非预期的急需处理事件,使得CPU暂时中断当前正在执行的程序而转去执行相应的事件处理程序,待处理完毕后又返回原来被 ...
- Linux系统编程——进程间通信:信号中断处理
什么是信号? 信号是 Linux 进程间通信的最古老的方式.信号是url=474nN303T2Oe2ehYZjkrggeXCaJPDSrmM5Unoh4TTuty4wSgS0nl4-vl43AGMFb ...
- linux系统编程之信号(二)
经过了漫长的间歇,对于c语言的学习也被中断了很久,现实确实有很多的无耐,计划中的事情总会被打乱,但不管怎样,学习的道路是不能休止的,所以经过了一断温习后现在继续学习C语言,话不多说,进入正题: 信号分 ...
随机推荐
- Activity之launchMode理解
对于Activity中的四个lauchMode[standard(默认).singleTop.singleTask.singleInstance]的介绍网上已经有大把的文章了,但是在实际应用开发时,对 ...
- centOS7 下 安装mysql8.x
第一部分 CentOS7安装mysql1.1 安装前清理工作:1.1.1 清理原有的mysql数据库:使用以下命令查找出安装的mysql软件包和依赖包: rpm -pa | grep mysql 显示 ...
- Markdown编辑器的使用测试
北京高校(大标题) 北京电子科技学院(小标题) 计算机技术(一级标) 研究生(二级标) 列表(三级标) 姓名 - 扎西 - 卓玛 学号 - 01 - 02 超链接 [QQ邮箱](https://www ...
- blind XXE payload
简单验证 POST /test HTTP/1.1 Content-Type: application/soap+xml User-Agent: scanner Accept: */* Cache-Co ...
- ORM补充
- LeetCode 317. Shortest Distance from All Buildings
原题链接在这里:https://leetcode.com/problems/shortest-distance-from-all-buildings/ 题目: You want to build a ...
- Laravel Repository Pattern
Laravel Repository Pattern The Repository Pattern can be very helpful to you in order to keep your ...
- Laravel 项目架构 弹性、可维护性
公司项目可能需要对架构进行重建,老大给了我一个视频让我学习里面的思想,看完后觉得收获很大,主讲人对laravel项目各个层次有很清晰的理解,力求做到职责单一分明,提高可维护性.下面是我看完视频对其内容 ...
- greenplum(postgresql) 数据字典
greenplum是基于postgresql开发的分布式数据库,里面大部分的数据字典是一样的.我们在维护gp的时候对gp的数据字典比较熟悉,特此分享给大家.在这里不会详细介绍每个字典的内容,只会介绍常 ...
- Codeforces 704E Iron Man [树链剖分,计算几何]
Codeforces 这题--真是搞死我了-- 好不容易下定了决心要不颓废,要写题,结果一调就调了十几个小时-- 思路 我们发现在树上做非常不舒服,于是树链剖分之后一次在重链上的移动就可以看做是在df ...