一篇文章彻底搞定信 !

?【干货】

嵌入式驱动工程师学习路线

?【干货】一个适合初学者的Linux物联 综合项目

?【干货】

Linux嵌入式知识点-思维导图

 1

1.信 是什么?

信 其实就是一个软件中断。

例:

输入命令,在Shell下启动一个前台进程。

用户按下Ctrl-C,键盘输入产生一个硬件中断。

如果CPU当前正在执行这个进程的代码,则该进程的用户空间代码暂停执行, CPU从用户态切换到内核态处理硬件中断。

终端驱动程序将Ctrl-C解释成一个SIGINT信 ,记在该进程的PCB中(也可以说发送了一个SIGINT信 给该进程)。

当某个时刻要从内核返回到该进程的用户空间代码继续执行之前,首先处理PCB中记录的信 ,发现有一个SIGINT信 待处理,而这个信 的默认处理动作是终止进程,所以直接终止进程而不再返回它的用户空间代码执行。

在这个例子中,由ctrl+c产生的硬件中断就是一个信 。Ctrl+C产生的信 只能发送给前台进程,命令后加&就可放到后台运行。Shell可同时运行一个前台进程和任意多个后台进程,只有前台进程才能接受到像CTRL+C这种控制键产生的信 。

2.信 的种类

使用命令查看:

非可靠信 :1~31 信 ,信 可能会丢失可靠信 :34~64 信 ,信 不可能丢失

SIGHUP:1 信 ,Hangup detected on controlling terminal or death of controlling process(在控制终端上挂起信 ,或让进程结束),ation:term

SIGINT:2 信 ,Interrupt from keyboard(键盘输入中断,ctrl + c),action:term

SIGQUIT:3 信 ,Quit from keyboard(键盘输入退出,ctrl+ |),action:core,产生core dump文件

SIGABRT:6 信 ,Abort signal from abort(3)(非正常终止,double free),action:core

SIGKILL:9 信 ,Kill signal(杀死进程信 ),action:term,该信 不能被阻塞、忽略、自定义处理

SIGSEGV:11 信 ,Invalid memory reference(无效的内存引用,解引用空指针、内存越界访问),action:core

SIGPIPE:13 信 ,Broken pipe: write to pipe with no readers(管道中止: 写入无人读取的管道,会导致管道破裂),action:term

SIGCHLD:17 信 ,Child stopped or terminated(子进程发送给父进程的信 ,但该信 为忽略处理的)

SIGSTOP:19 信 ,Stop process(停止进程),action:stop

SIGTSTP:20 信 ,Stop typed at terminal(终端上发出的停止信 ,ctrl + z),action:stop

具体的信 采取的动作和详细信息可查看:man 7 signal

3.信 的产生

3.1硬件产生

硬件产生即通过终端按键产生的信 :

ctrl + c:SIGINT(2),发送给前台进程,& 进程放到后台运行,fg 把刚刚放到后台的进程,再放到前台来运行

ctrl + z:SIGTSTP(20),一般不用,除非有特定场景

ctrl + | :SIGQUIT(3),产生core dump文件

产生core dump文件的条件:

3.2软件产生

软件产生即调用系统函数向进程发信

kill函数

kill命令:kill -[信 ] pid,

abort:void abort(void);,收到6 信 ,谁调用该函数,谁就收到信

alarm:unsigned int alarm(unsigned int seconds);,收到14 信 ,告诉内核在seconds秒后给进程发送SIGALRM信 ,该信 默认处理动作为终止当前进程。

4.信 的注册

信 注册又分为可靠信 的注册和非可靠信 的注册。信 注册实际上是一个位图和一个sigqueue队列。

4.1非可靠信 的注册

当进程收到非可靠信 时:

将非可靠信 对应的比特位置为1

添加sigqueue节点到sigqueue队列当中,但是,在添加sigqueue节点的时候,队列当中已然有了该信 的sigqueue节点,则不添加

4.2可靠信 的注册

当进程所受到可靠信 时:

在sig位图中更改信 对应的比特位为1不论之前sigqueue队列中是否存在该信 的sigqueue节点,都再次添加sigqueue节点到sigqueue队列当中去

5.信 的注销

5.1非可靠信 的注销

信 对应的比特位从1置为0将该信 的sigqueue节点从sigqueue队列当中进行出队操作

5.2可靠信 的注销

将该信 的sigqueue节点从sigqueue队列当中进行出队操作需要判断sigqueue队列当中是否还有相同的sigqueue节点:①没有了:信 比特位从1置为0②还有:不会更改sig位图中的比特位

6.信 阻塞

6.1信 是怎样阻塞的?

信 的阻塞,并不会干扰信 的注册。信 能注册,但不能被立即处理,将block位图中对应的信 比特位置为1,表示阻塞该信 进程收到该信 ,还是一如既往的注册当进程进入到内核空间,准备返回用户空间的时候,调用do_signal函数,就不会立即去处理该信 了当该信 不被阻塞后,就可以进行处理了

6.2sigprocmask

函数原型:int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);参数解释:

例:下述例子,信 全部被阻塞,采用kill -9,将该进程结束掉

结果: 此时发送信 是不会有作用的,采用kill -9强杀掉

7.信 未决

7.1 未决概念

实际执行信 的处理动作称为信 递达(Delivery),信 从产生到递达之间的状态,称为信 未决(Pending)。进程可以选择阻塞(Block)某个信 。被阻塞的信 产生时将保持在未决状态,直到进程解除对此信 的阻塞,才执行递达的动作。注意,阻塞和忽略是不同的,只要信 被阻塞就不会递达,而忽略是、在递达之后可选的一种处理动作。

7.2 sigpending

函数原型:int sigpending(sigset_t *set);读取当前进程的未决信 集,通过set参数传出。调用成功返回0,出错返回-1.

例:

结果:

8.信 的处理方式

在上述例子中:

SIGHUP信 未阻塞也未产生过,当它递达时执行默认处理动作。

SIGINT信 产生过,但正在被阻塞,所以暂时不能递达。虽然它的处理动作是忽略,但在没有解除阻塞之前不能忽略这个信 ,因为进程仍有机会改变处理动作之后再解除阻塞。

SIGQUIT信 未产生过,一旦产生SIGQUIT信 将被阻塞,它的处理动作是用户自定义函数sighandler。

8.1signal函数

该函数可以更改信 的处理动作。

实际上,该函数内部也调用了sigaction函数。

8.2sigaction函数

读取和修改与指定信 相关联的处理动作。

参数解释:

struct sigaction结构体:

例:

结果:

8.3 自定义信 处理的流程

task_struct结构体中有一个struct sighand_struct结构体。

struct sighand_struct结构体有一个**struct k_sigaction action[_NSIG]**结构体数组。

该数组中,其中的**_sighandler_t sa_handler**保存的是信 的处理方式,通过改变其指向,可以实现我们对自定义信 的处理。

9.信 的捕捉

9.1信 捕捉的条件

如果信 的处理动作是用户自定义函数,在信 递达时就调用这个函数,这就称为信 捕捉。

9.2信 捕捉流程

内核态返回用户态会调用do_signal函数,两种情况:

无信 :sys_return函数,返回用户态

有信 :先处理信 ,信 返回,再调用do_signal函数例:

程序注册了SIGQUIT信 的处理函数sighandler。

当前正在执行main函数,这时发生中断或异常切换到内核态。

在中断处理完毕后要返回用户态的main函数之前检查到有信 SIGQUIT递达。

内核决定返回用户态后不是恢复main函数的上下文继续执行,而是执行sighandler函数, sighandler和main函数使用不同的堆栈空间,它们之间不存在调用和被调用的关系,是两个独立的控制流程。

sighandler函数返回后自动执行特殊的系统调用sigreturn再次进入内核态。

如果没有新的信 要递达,这次再返回用户态就是恢复main函数的上下文继续执行了。

10.常用信 集操作函数

11.SIGCHLD信

该信 是子进程在结束是发送给父进程的信 ,但是该信 的处理方式是默认处理的。父进程对子进程发送过来的SIGCHLD信 进行了忽略处理,就会导致子进程成为僵尸进程。

可以自定义该信 的处理方式:

指令查看后台:ps aux | grep ./fork

原文地址: 

https://blog.csdn.net/w903414/article/details/109802539?utm_source=app&app_version=4.18.0&utm_source=app

一口Linux 

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年9月26日
下一篇 2022年9月26日

相关推荐