进程空间分为用户空间和内核空间 。此前我们介绍的页表都是用户级页表,其实还有内核级页表 。进程的用户空间是通过用户级页表映射到物理内存上,内核空间是通过内核级页表映射到物理内存上,如下面简图所示:

文章插图

文章插图
- 当进程运行在内核空间时就处于内核态,而进程运行在用户空间时则处于用户态 。
- 最高 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的同义词
- 2022年农历十一月十二适合乔迁吗
- 二 SpringCloud - Eureka注册中心,feign远程调用,hystrix降级和熔断
- 2022年腊月初二是阳历几月几号
- 2022年腊月初二日子吉利吗