目录
1.什么是信号
2.信号的产生
处理信号的常见方式:
如何理解这些组合键是如何变成信号的?
信号发送本质编辑
信号的种类
编辑
3.信号处理常见方式概览
4.产生信号
5.信号其他相关常见概念
编辑
6.捕捉信号
signal函数:
7.可重入函数
8.一些题
本质是一种通知机制,用户or操作系统通过发送一定的停号,通知进程,某些事件已经发生,你可以在后续进行处理
1.1.结合进程,分析信号
a.进程要分析信号,必须要识别信号即,进程要接收并且要具备其如何处理的动作。
b.进程如何识别信号呢?通过程序员设置的方式让进程去识别。
c.信号的产生是随机的,所以进程的处理方式可能不是立即处理,而是将信号存储起来,在合适的场合处理。
d.进程会降临是信号进行存储,方便之后的处理。
e.一般而言,信号的产生相对于进程来说是异步的
通过键盘的组合键产生
比如:通过Ctrl+c终止进程,是向目标进程发送2号信号,这就是一种通过键盘向进程发送信号,让进程退出了。
默认;忽略;自定义(捕捉信号)一共有这三种处理方式。
键盘的工作方式是通过中断的方式进行的,OS解释组合键,然后在进程列表中查找,找到前台运行的进程,OS将信号写入当前的进程结构中的位图中。
先思考一个问题:信号是什么时候被处理的
首先,不是立即被处理的。而是在合适的时候,这个合适的时候,具体指的是进程从用户态切换回内核态时进行处理。
用户态: 处于⽤户态的 CPU 只能受限的访问内存,用户的代码,并且不允许访问外围设备,权限比较低。
内核态: 处于内核态的 CPU 可以访问任意的数据,包括外围设备,⽐如⽹卡、硬盘等,权限比较高。
注意: 操作系统中有一个cr寄存器来记录当前进程处于何种状态
signal(int signum, sighandler_t handler);
第一个参数为信号,可以是信号的编号,也可以是信号的名称,第二个参数是一个回调函数,通过回调函数处理信号,可以为默认,忽略,自定义。默认和忽略所对应的参数名称为:SIG_DFL,SIG_IDO。自定义的参数需要自己写回调函数去完成。通过回调的方式,去修改对应的信号捕捉方法。
#include
#include
void sigcb(int signal)
{
printf("触发本次事件的信号值:%d\n", signal);
}
int main()
{
// 设置SIGINT信号的处理函数为sigcb
signal(SIGINT, sigcb);
// 死循环,等待SIGINT信号触发
while (1)
{
}
return 0;
}
//当您运行这段代码后,在终端中按下Ctrl+C(发送SIGINT信号),"sigcb"函数将被调用,并打印出触发本次事件的信号值。
函数的重入指的是一个函数在不同执行流中同时进入运行,其中不可重入指的是一旦重入就有可能会出问题,而可重入就是不管怎么重入都不会有特殊影响
在一个函数中若对全局变量进行了原子操作,则这个函数一定是可重入的
自定义信号捕捉函数 signal函数 sigaction函数
SIGSTOP/SIGKILL信号无法被阻塞,无法被自定义,无法被忽视
Ctrl+C会向当前终端的前台进程发送SIGINT信号,中断正在运行在前台的程序
Ctrl+Z会使当前终端的前台进程进入停止态而不是退出
raise接口可以向当前调用进程发送任意信号
未决信号是在从程序运行在内核态返回用户态的时候进行处理
只有自定义处理方式的信号会在用户态进行处理
自定义处理方式的信号会在执行完信号捕捉函数后先返回内核态
1. 一个进程无法被kill杀死的可能有哪些?
A.这个进程阻塞了信号
B.用户有可能自定义了信号的处理方式
C.这个进程有可能是僵尸进程
D.这个进程当前状态是停止状态
都对 ABCD
2.程序运行从用户态切换到内核态的操作:中断/异常/系统调用
I. 整数除以零
II. sin()函数调用
III. read 系统调用
I 会导致程序异常(分母不能为0)
II 库函数并不会引起运行态的切换
III 系统调用接口