守听 发表于 2024-11-3 19:15:09

【linux】信号(上)

 https://i-blog.csdnimg.cn/direct/fb5a40668f9d47618e126b85ba51ac33.png
1. 认识信号

信号是进程之间变乱异步通知的一种方式,属于软停止

留意:

[*]进程一定要有识别和处置惩罚信号的能力(即使信号没有产生,也要具备处置惩罚信号的能力,并且处置惩罚信号的能力,属于进程内置的一部分)
[*]当一个进程收到了一个信号的时候,不一定会立刻处置惩罚这个信号
[*]一个进程从信号产生,到信号被处置惩罚的这个阶段,会偶然间窗口,即进程具有临时生存哪些信号已经发生的能力
2. 信号处置惩罚常见方式概览

处置惩罚信号分三种


[*]忽略此信号。
[*]执行该信号的默认处置惩罚动作(进程内置了,每一种信号有差异的处置惩罚方式)
[*]提供一个信号处置惩罚函数,要求内核在处置惩罚该信号时切换到用户态执行这个处置惩罚函数,这种方式称为捕捉
(Catch)一个信号,(即自界说动作,自己规定哪一种信号对应哪一种处置惩罚方式)

3. 技术应用角度的信号

1. 用户输入下令,在Shell下启动一个前台进程
用户按下Ctrl+C ,这个键盘输入产生一个硬件停止,被OS获取,表明成信号,发送给目的前台进程
前台进程因为收到信号,进而引起进程退出
   画图表明

https://img-blog.csdnimg.cn/img_convert/56c6a0eca3626e7d18d1d7ed784d6503.png

留意:

[*]linux 中,一次登岸,一个终端,一样平常会配上一个 bash,每一个登录都只允许有一个前台进程(键盘上的输入,都是发送给前台进程的),可以允许有多个背景进程
[*]Ctrl+C 被表明成2号信号
[*]Ctrl-C 产生的信号只能发给前台进程。一个下令后面加个&可以放到背景运行,这样Shell不必等待进程结束就可以接受新的下令,启动新的进程

4. 系统界说的信号列表

   

[*]kill -l

https://img-blog.csdnimg.cn/img_convert/70788686f61e4191db01957adbc5dda1.png
留意:
1 ~ 31 : 平凡信号(一样平常以位图的情势储存在对应的进程PCB中,tast_struct 中有 signal ,此中比特位的 0 ,1 表现是否收到信号,比特位的位置(第几个)表现信号编号,所谓的发送信号就是更改对应进程信号位图的比特位)
这里是存在一些问题,如:信号可以发送很多次,但是迟迟没有处置惩罚信号,导致处置惩罚次数和发送信号次数不对等(处置惩罚次数可能会减少)
34 ~ 64 : 实时信号(接受信号后,立刻处置惩罚信号,一样平常以链表的情势存储,以是发送信号次数和处置惩罚次数是一样的)


[*]man 7 signal

5. 修改特定的进程对于信号处置惩罚的动作

   signal函数
功能:修改特定的进程对于信号处置惩罚的动作
typedef void (*sighandler_t)(int);

原型:
sighandler_t signal(int signum,sighandler_t handler);
参数:
signum:信号编号(可以通过查察信号列表得到)
handler:自界说处置惩罚方法
    代码

https://img-blog.csdnimg.cn/img_convert/bec0f80776af285cfc67105455253c80.png

https://img-blog.csdnimg.cn/img_convert/0a32c38644efe89c0acc18987348e400.png

留意:
signal函数只需要调用一次,往后都有效,且只有产生信号的时候,才会执行对应的方法

6. 信号的产生方式

1. 键盘组合键
如:Ctrl + C --- 2号信号 Ctrl + \ ---- 3号信号
2. kill 下令
kill -信号编号 + 进程pid
3. 系统调用


[*]kill函数


[*]raise函数
[*]abort函数
4. 软件产生信号
如: 管道发送读端关闭,写段正常,此时会产生信号,杀死进程


7. 产生信号

(一)通过终端按键产生信号


https://img-blog.csdnimg.cn/img_convert/afbc4b8ecf9c61ae5335e25aab96ab48.png
留意:
Term 和 Core 都是会退出进程

Core Dump


[*]Core Dump概念: 当一个进程要异常停止时,可以选择把进程的用户空间内存数据全部生存到磁盘上,文件名通常是core,这叫做Core Dump。(即 假如打开系统的 core dump 功能,一旦进程异常,OS 会将进程在内存中的运行信息,转储到进程的当前目录(磁盘)形成 core.pid 文件)
[*]一个进程允许默认是不允许产生core文件的(因为core文件中可能包罗用户密码等敏感信息,不安全)
[*]在开发调试阶段可以用ulimit下令改变这个限定,允许 产生core文件。 首先用ulimit下令改变Shell进程的Resource Limit,允许core文件最大为1024K: 如 ulimit -c 1024

   

https://img-blog.csdnimg.cn/img_convert/752ff67643690988a3ed6d2f79644f04.png
写一个死循环,终端输入Ctrl + \ ,得到如下:

https://img-blog.csdnimg.cn/img_convert/26d5987c132803e6c28dbcef5ce4465f.png

留意:
进程异常停止通常是因为有Bug,比如非法内存访问导致段错误, 过后可以用调试器检查core文件以查清错误原因,这叫做过后调
(二)调用系统函数向进程发信号



[*]kill函数
int kill(pid_t pid,int sig);
pid : 进程pid ; sig : 信号编号


[*]raise函数
int raise(int sig);


[*]abort函数
void abort(void)
发送6号信号,且不管是否是否对6号自界说处置惩罚动作,都一定会退出进程

3. 由软件条件产生信号
这里主要介绍alarm 函数
   原型:
unsigned int alarm(unsigned int seconds);

返回值:
因为 alarm 可以被多次调用,返回值是上一次alarm函数调用剩下的秒数(有可能上一个alarm函数时间没到,又被调用了)

留意:
调用alarm函数可以设定一个闹钟,也就是告诉内核在seconds秒之后给当进步程发SIGALRM信号, 该信号的默认处置惩罚动作是停止当进步程

(三)硬件异常产生信号

硬件异常被硬件以某种方式被硬件检测到并通知内核,然后内核向当进步程发送适当的信号
(如当进步程执行了除以0的指令,CPU的运算单元会产生异常,内核将这个异常表明 为SIGFPE信号发送给进程。又如当进步程访问了非法内存地址,MMU会产生异常,内核将这个异常表明为SIGSEGV信号发送给进程)

https://img-blog.csdnimg.cn/img_convert/0bfa23ed20104efbd166e7f9ff318a7d.png

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 【linux】信号(上)