信号的捕获一个进程收到一个信号的时候,可以用以下的方法进行处理:
(1)执行系统默认动作:对大多数信号来说,系统默认动作就是来终止进行 。
(2)忽略此信号(丢弃):接收到此信号后没有任何动作
(3)执行自定义信号处理函数(捕获):用户定义的信号处理函数处理该信号
注意:SIGKILL和SIGSTOP不能更改信号的处理方式 , 因为它们向用户提供了一种使进程终止的可靠方法 。
信号捕捉的过程先思考一个问题:信号是什么时候被进程处理的?
首先,不是立即被处理的 。而是在合适的时候 , 这个合适的时候,具体指的是进程从用户态切换回内核态时进行处理
这句话如何理解,什么是用户态?什么是内核态?
- 用户态: 处于?户态的 CPU 只能受限的访问内存,用户的代码,并且不允许访问外围设备,权限比较低
- 内核态: 处于内核态的 CPU 可以访问任意的数据,包括外围设备,?如?卡、硬盘等,权限比较高
进程空间分为用户空间和内核空间 。此前我们介绍的页表都是用户级页表 , 其实还有内核级页表 。进程的用户空间是通过用户级页表映射到物理内存上,内核空间是通过内核级页表映射到物理内存上,如下面简图所示:

文章插图

文章插图
- 当进程运行在内核空间时就处于内核态,而进程运行在用户空间时则处于用户态 。
- 最高 1G 的内核空间是被所有进程共享的!
信号捕捉的整个过程:

文章插图
从上面的图可以看出,进程是在返回用户态之前对信号进行检测,检测pending位图,根据信号处理动作,来对信号进行处理 。这个处理动作是在内核态返回用户态后进行执行的,所以这里也就回答了开始提出的那一个问题了 。
sigaction函数
#include <signal.h>int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);功能:检查或修改指定信号的设置(或同时执行两种操作)参数:signum:要操作的函数act:要设置的对信号的新处理方式(传入方式)oldact:原来对信号的处理方式(传出参数)如果act指针非空,则要改变指定信号的处理(设置),如果oldact指针非空,则系统将此前指定信号的处理方式入oldact返回值:成功:0失败:-1
struct sigaction结构体:struct sigaction { void(*sa_handler)(int);//旧的信号处理函数指针void(*sa_sigaction)(int, siginfo_t *, void *);//新的信号处理函数指针sigset_tsa_mask;//信号阻塞集intsa_flags;//信号处理的方式void(*sa_restorer)(void);//已经弃用};
(1)sa_handler、sa_sigaction:信号处理函数指针 , 和signal里面的函数指针用法是一样的,根据情况给两个指针赋值 。?a)SIG_IGN:忽略该信号
?b)SIG_DFL:执行系统默认的动作
?c)处理函数名:自定义信号处理函数
(2)sa_mask:信号阻塞集,在执行信号处理函数的时候 , 用来临时的屏蔽信号
(3)sa_flags:用于指定信号处理的行为,通常设置为0,表示使用默认的属性 。它可以是一下值的“按位”或“组合”:
- SA_NOCLDSTOP:使父进程在它的子进程暂停或继续运行时不会收到SIGCHLD信号 。
- SA_NOCLDWAIT:使父进程在它的子进程退出的时候不会收到SIGCHLD信号,这时子进程如果退出也不会成为僵尸进程 。
- SA_NODEFER:使对信号的屏蔽无效,即在信号处理函数执行期间仍能发出整个信号 。
- SA_RESETHAND:信号处理之后重新设置为默认的处理方式 。
- SA_SIGINFO:使用sa_sigaction成员而不是sa_handler作为信号处理函数 。
#include <stdio.h>#include <unistd.h>#include <signal.h>void handler(int signo){printf("catch a signal: %d\n", signo);}int main(){struct sigaction act, oact;act.sa_flags = 0;// 选项 设置为0sigfillset(&act.sa_mask);act.sa_handler = handler;// 对2号信号修改处理动作sigaction(2, &act, &oact);while (1){raise(2);sleep(1);}return 0;}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- too同义词|too的同义词
- 二 SpringCloud - Eureka注册中心,feign远程调用,hystrix降级和熔断
- 焊工证个人信息查询入口 查询入口
- Docker在windows系统以及Linux系统的安装
- 二 京东云开发者| Redis数据结构-List、Hash、Set及Sorted Set的结构实现
- 一篇文章带你了解服务器操作系统——Linux简单入门
- 二、python基本数据类型
- 二 【SSM】学习笔记——SpringMVC入门
- 原神片剂深研第二关怎么通关
- 一步一图带你深入理解 Linux 虚拟内存管理