《linux从0到99》十一进程信号(代码片段)

AURORA_CODE AURORA_CODE     2022-12-12     253

关键词:

一、 信号的概念

信号是进程之间事件异步通知的一种方式,属于软中断。

二、 信号的种类

在linux下使用kill -l命令可以查看系统定义的信号列表

  • 每个信号都有一个编号和一个宏定义名称,这些宏定义可以在signal.h中找到,例如其中有定 义 #define SIGINT 2
  • 编号34以上的是实时信号,本章只讨论编号34以下的信号,不讨论实时信号。这些信号各自在什么条件下产生,默认的处理动作是什么,在signal(7)中都有详细说明: man 7 signal

1. 非可靠信号 (非实时信号)

[1,31]:不可靠,信号可能会丢失

2. 可靠信号 (实时信号)

[34,64]:可靠信号,信号绝对不会丢失

三、 信号的产生方式

1. 硬件产生

CRTL + c : 二号信号
CRTL + | : 三号信号 SIGQUIT
CRTL + z : 20号信号 SIGTSTP

2. 软件产生

kill命令产生: kill -9 命令等。
函数: abort() --> 6号信号 , alarm() --> 14号信号

四、 信号的注册


sigqueue队列:
前提:同一个信号申请俩次

非可靠信号的注册:

  • 第一次将对应的比特位改为1+在sigqueue队列中添加sigqueue节点
  • 第二次只会将对应的比特位改位1,不添加sigqueue节点。

可靠信号的注册:

  • 第一次将对应的比特位改为1+在sigqueue队列中添加sigqueue节点
  • 第二次还会再sigqueue队列中添加sigqueue节点。

五、 信号的注销

非可靠信号的注销:

  • 将信号在sig位图中对应的比特位置0;并将sigqueue节点在sigqueue队列中出队。

可靠信号的注销:

  • 将可靠信号对应的sigqueue节点在sigqueue队列中出队
  • 判断sigqueue队列中是否还有该可靠信号对应的sigqueue节点。如果没有,将sig位图中对应的比特位置0;如果有,则不会将sig位图中对应的比特位置0

六、 信号的处理方式

  1. 默认处理方式
  2. 忽略处理
  3. 自定义处理

七、 信号的捕捉流程

1. 内核如何实现信号的捕捉

如果信号的处理动作是用户自定义函数,在信号递达时就调用这个函数,这称为捕捉信号。由于信号处理函数的代码是在用户空间的,处理过程比较复杂,举例如下: 用户程序注册了SIGQUIT信号的处理函数sighandler。 当前正在执行main函数,这时发生中断或异常切换到内核态。 在中断处理完毕后要返回用户态的main函数之前检查到有信号SIGQUIT递达。 内核决定返回用户态后不是恢复main函数的上下文继续执行,而是执行sighandler函 数,sighandler和main函数使用不同的堆栈空间,它们之间不存在调用和被调用的关系,是 两个独立的控制流程。 sighandler函数返回后自动执行特殊的系统调用sigreturn再次进入内核态。 如果没有新的信号要递达,这次再返回用户态就是恢复main函数的上下文继续执行了。

02. sigaction

#include <signal.h>
int sigaction(int signo, const struct sigaction *act, struct sigaction *oact); 
  • sigaction函数可以读取和修改与指定信号相关联的处理动作。调用成功则返回0,出错则返回- 1。signo是指定信号的编号。若act指针非空,则根据act修改该信号的处理动作。若oact指针非 空,则通过oact传出该信号原来的处理动作。act和oact指向sigaction结构体:
  • 将sa_handler赋值为常数SIG_IGN传给sigaction表示忽略信号,赋值为常数SIG_DFL表示执行系统默认动作,赋值为一个函数指针表示用自定义函数捕捉信号,或者说向内核注册了一个信号处理函 数,该函数返回值为void,可以带一个int参数,通过参数可以得知当前信号的编号,这样就可以用同一个函数处理多种信号。显然,这也是一个回调函数,不是被main函数调用,而是被系统所调用。

当某个信号的处理函数被调用时,内核自动将当前信号加入进程的信号屏蔽字,当信号处理函数返回时自动恢复原来的信号屏蔽字,这样就保证了在处理某个信号时,如果这种信号再次产生,那么 它会被阻塞到当前处理结束为止。 如果在调用信号处理函数时,除了当前信号被自动屏蔽之外,还希望自动屏蔽另外一些信号,则用sa_mask字段说明这些需要额外屏蔽的信号,当信号处理函数返回时自动恢复原来的信号屏蔽字。

八、 信号的阻塞

信号的阻塞指的是当准备处理信号的时候,会判断当前信号是否为阻塞,如果该信号为阻塞,则暂时不去处理该信号。

1. block位图

2. sigprocmask函数

int sigprocmask(int how , const sigset_t *set, sigset_t *oldset)
	how : 告诉sigprocmask函数以什么方式进行工作
		SIG_BLOCK : 设置某个信号为阻塞状态
		SIG_UNBLOCK : 解除信号的阻塞状态
		SIG_SETMASK : 替换原来的block位图
			SIG_BLOCK :
				block(new) = block(old)&bolck(~set)
					block(old) : 0010 1100
								 1111 1011
					set		   : 0000 0100 (1111 1011)
			SIG_SETMASK :
				block(new) = set
		oldset : 在没有更改之前的老的block位图
		

3.验证可靠信号和非可靠信号

  1. 信号的阻塞不会干扰信号的注册
  2. 可靠信号在收到多次就会处理多次,而非可靠信号收到多次,只会处理一次。非可靠信号可能会导致信号的丢失。

以上就是这篇文章的所有内容啦,感谢老铁有耐心看完。有啥错误请多多指正哈!码字不易,希望大佬们点个赞

《linux从0到99》十一进程信号(代码片段)

进程信号一、信号的概念二、信号的种类1.非可靠信号(非实时信号)2.可靠信号(实时信号)三、信号的产生方式1.硬件产生2.软件产生四、信号的注册五、信号的注销六、信号的处理方式七、信号的捕捉流程1.内... 查看详情

《linux从0到99》八进程控制(代码片段)

LINUX进程控制1.进程创建(fork)2.进程终止01_exit函数02exit函数03atexit函数04return退出3.进程等待01进程等待的必要性02进程等待的方法a)wait函数b)waitpid函数03获取子进程status5.进程替换01进程替换原理02进程替换函数6.利用所学... 查看详情

《linux从0到99》六进程概念下(代码片段)

进程概念下1.僵尸进程01僵尸进程的概念03解决僵死状态/僵尸进程04僵尸进程的模拟实现05僵尸进程的危害2.孤儿进程01孤儿进程的概念02孤儿进程的模拟实现03孤儿进程的危害3.进程优先级01PRIandNI02PRIvsNI查看进程优先级的命令4.环境... 查看详情

《linux从0到99》五进程概念上(代码片段)

进程概念上1.冯·诺依曼体系结构2.操作系统01概念02设计OS的目的03OS的定位04对OS所谓管理的理解3.进程01基本概念02描述进程PCB1)task_struct-PCB的一种2)task_struct内容分类03查看进程04通过系统调用获得进程标识符05通过系统... 查看详情

《linux从0到99》十进程间通信(代码片段)

进程间通信一、什么是进程间通信1.进程间通信的目的2.进程间通信的分类二、管道1.管道01管道的符号02管道的本质2.匿名管道与命名管道01匿名管道02命名管道三、消息队列四、共享内存1.共享内存的原理2.共享内存接口01shmget02shm... 查看详情

《linux从0到99》十进程间通信(代码片段)

进程间通信一、什么是进程间通信1.进程间通信的目的2.进程间通信的分类二、管道1.管道01管道的符号02管道的本质2.匿名管道与命名管道01匿名管道02命名管道三、消息队列四、共享内存1.共享内存的原理2.共享内存接口01shmget02shm... 查看详情

《linux从0到99》八进程控制(代码片段)

LINUX进程控制1.进程创建(fork)2.进程终止01_exit函数02exit函数03atexit函数04return退出3.进程等待01进程等待的必要性02进程等待的方法a)wait函数b)waitpid函数03获取子进程status5.进程替换01进程替换原理02进程替换函数6.利用所学... 查看详情

linux从青铜到王者第十二篇:linux进程间信号第二篇(代码片段)

系列文章目录文章目录系列文章目录前言一、阻塞信号1.信号其他相关常见概念2.在内核中的表示3.sigset_t信号集4.信号集操作函数5.sigprocmask函数6.sigpending函数二、捕捉信号1.内核实现信号的捕捉2.volatile关键字总结前言一、阻塞信... 查看详情

linux进程通信|信号(代码片段)

...号是一种软件中断,它通常是异步发生的,可以用来通知进程某个事件已经发生。。每个信号都有一个唯一的编号,编号从1开始。进程可以通过注册信号处理函数来处理信号。二、信号的分类Linux系统中的信号有两类:标准信号... 查看详情

《linux从0到99》九基础io(代码片段)

基础IO1.回顾c语言文件操作接口2.系统调用文件操作系统01open函数02read函数03write函数04lseek函数05close函数3.文件描述符0&1&2文件描述符的分配规则(最小未分配原则)4.文件描述符与文件流指针的区别01文件流指针的本... 查看详情

《linux从0到99》三yum与vim编辑器(代码片段)

...软件包在Linux下安装软件,最常用的办法是下载到程序的源代码,并进行编译 查看详情

《linux从0到99》四linux编译器(gcc/g++)和调试器(gdb)(代码片段)

...项目清理1.Linux编译器gcc/g++使用01预处理主要处理源代码文件中的以“#”开头的预编译指令。删除所有的#define并展 查看详情

嵌入式linux从入门到精通之第十一节:进程间通信

进程间通信(IPC:InterProcessesCommunication)进程是一个独立的资源分配单元,不同进程(这里所说的进程通常指的是用户进程)之间的资源是独立的,没有关联,不能在一个进程中直接访问另一个进程的资源(例如打开的文件描述符)... 查看详情

shell从入门到精通(10)信号捕获和处理(代码片段)

前言Linux利用信号与运行在系统中的进程进行通信。当你在终端中启动一个前台进程,按下(Ctrl+C),Linux内核会生成SIGINT信号中断该进程。而trap命令可以在信号出现时捕获,修改信号的默认处理动作。捕获信号trap命令允许你来指... 查看详情

linux信号+再谈进程地址空间(代码片段)

...产生信号4.1八号信号SIGFPE(除零错误可引发)4.2十一号信号SIGSEGV(段错误可引发)5、软件条件产生异常5.1十三号信号SIGPIPE(匿名管道读端关闭,写端收到该信号)5.2十四号信号SIGALRM(定时器)... 查看详情

linux进程信号(代码片段)

让一路花香满径,让紫日安暖自若。linux进程信号什么是信号从生活中角度进程间信号信号概念信号列表信号的产生通过键盘产生信号CoreDump(为了定位错误)通过系统调用函数向进程发信号由软件条件来产生信号硬件异常产生... 查看详情

linux信号一门搞定(代码片段)

...软件中断。例:输入命令,在Shell下启动一个前台进程。用户按下Ctrl-C,键盘输入产生一个硬件中断。如果CPU当前正在执行这个进程的代码,则该进程的用户空间代码暂停执行,CPU从用户态切换到内核态处理硬... 查看详情

linux进程信号(代码片段)

...用户态2.信号捕捉过程九、可重入函数十、关键字volatile十一、SIGCHLD信号一、生活信号生活中有很多的信号,比如闹钟、消息提醒、手机铃声,红绿灯。但是人是怎么识别红绿灯的,识别信号的?通过认识产生行... 查看详情