当前位置: 首页 > article >正文

linux-信号

信号是发给进程的,进程接收到信号后会有内置的对应信号的处理行为。

信号是操作系统发给进程的,用户只是让操作系统发给进程。

进程必须要有识别信号,并且处理对应信号的能力。

即使没有收到信号,也需要直到该信号的处理方法。

在进程收到信号时,也许并不适合立即处理该信号,会把这个信号保存起来,合适的时候再进行处理。

并不适合立即处理该信号也就是进程正处于内核态,内核态拥有访问操作系统内部的权限,在进程地址空间当中3gb到4gb的这一个gb空间是属于内核空间,只有内核态才能访问,而内核态和用户态是由cpu当中的一个寄存器来决定的。

在进行系统调用这些操作就会进入内核态。

也就是说,在信号产生时到信号被处理之前,会有时间窗口,进程具有分辨哪些信号被处理了的能力。

自定义信号处理

用户也可以将信号处理的动作自定义,让这个信号的处理按照自己定义的来执行。

前台进程和后台进程

前台进程就是接收键盘数据的进程,每一个中断都会分配一个bash,每一个终端前台进程只有一个。

执行信号的处理动作被称为信号递达。

信号从产生到递达之间的状态,称为信号未决。

进程可以选择阻塞某个信号,被阻塞的信号会被保持在未决状态,不会被处理,直到进程解除了对该信号的阻塞,才执行递达的动作。

阻塞是信号不会递达,忽略是信号处理的一个选项。

信号捕捉

在信号被处理的时候,该信号会被屏蔽,这是为了同一信号在处理期间不会再被调用。在该信号处理完毕后会自动解除屏蔽。

signal

这个系统调用可以将原本的信号捕捉处理覆盖,变成用户设置的自定义处理方式。

但并不是所有的信号都可以被捕捉的

第一个参数signum是一个整数,信号实际上就是整数定义的宏。

左边的顺序编号实际上就是这些宏定义信号实际的整数。

第二个参数是一个参数为int返回值为void的函数指针。 

也可以输入宏SIG_IGN忽略这个信号 SIF_DFL默认信号处理方式

sigaction和signal一样是信号捕捉的系统调用

第一个参数和signal一样是要捕捉信号对应的整数。

第二个参数是一个数据结构 

这个数据结构一般只需要关注两个变量

一个是以int为参数,返回值为void的函数指针,和signal一样,是信号的处理方法。

还有一个是sigset_t位图类型的结构体变量,这个参数的作用是在处理该信号时,会将该结构体变量当中置1的信号一起屏蔽。 

第三个参数是输出型参数,会保存之前的sigaction结构。

信号产生方式

键盘产生

指令产生

系统调用

让指定进程执行对应信号处理方式 

第一个参数是进程pid,第二个参数是信号对应整数

让调用的进程执行对应信号处理方式

sig是信号对应的整数 

让调用进程被中断 。

闹钟

这是一个系统调用,参数是整数,作用是以秒为单位,输入参数秒后对进程发送一个14号信号。 

返回参数是调用这个系统调用时上一个alarm调用还有几秒发送信号。

进程等待的core dump

在父进程等待子进程,接收到返回数据时,除了错误码和终止信号,还有core dump,这是一个在传入参数的第8个比特位,代表的意思是收到的终止信号是错误信号还是常规的信号,错误信号就把这个比特位置为1,不是就置为0.

但是core dump信号还需要打开。

如果是错误信号,就会在进程运行的当前目录建立一个文件,core.进程pid,使用 core-file调用这个文件,能直接定位到出错行。

信号保存

信号实际上是通过进程指向的指针来完成的,block是一个位图结构,0表示没有屏蔽该信号,1表示屏蔽了该信号。

屏蔽信号也就是这个信号不会被处理。

pending也是一个位图结构,0是信号已被处理,1是信号未处理。

handler是一个函数指针数组,指向着不同的处理方法。 

操作系统提供了一系列的系统调用来供用户使用。

#include <signal.h>

int sigemptyset(sigset_t *set);

int sigfillset(sigset_t *set);

int sigaddset (sigset_t *set, int signo);

int sigdelset(sigset_t *set, int signo);

int sigismemberconst sigset_t *set, int signo);

sigset是一个位图结构

sigemptyse 可以将指针指向的sigset类型的pending全部清零

函数sigfillset可以将指针指向的pending全部置一。

sigaddset可以将指定的位图结构当中指定信号位置为1.

sigdelset可以将指定位图结构当中指定信号位置为0.

sigismember可以对指定位图结构当中指定信号位进行判断,有信号返回1,没信号返回0

第一个参数是位图结构,第二个参数是指定信号

sigpending可以将pending表当中的位图结构拷贝一份出来

set是一个输出型参数,将用户自定义的位图结构传进去,会将pending位图结构拷贝一份出来。

sigprocmask的参数有三个。

第一个参数是一个整数,定义了三个宏,第一个宏是将传入的位图结构进行或运算。第二个是将传入的位图结构取反后与原本的位图进行与运算。第三个宏是直接将传入的位图结构替换原本的位图结构。

第二个参数是一个位图结构,将自己定义好的位图结构传入进行第一个参数对应的运算

第三个参数是一个输出型参数,会保存进行运算之前的位图结构

从这些系统调用可以看出,操作系统并不希望用户直接拿到可以修改这些位图结构的地址,而是通过系统调用将位图结构拷贝一份出来,可以让用户知道位图结构的参数。要修改位图的话也是将位于栈区的用户自己创建的位图结构传过去,根据这个为统一结构进行修改。 

而不能及时处理信号的状态就是内核态,在调用系统调用等一系列的操作时,会从用户态转进内核态,在内核态转换成用户态之前会检查一遍信号,如果有需要处理的信号那就直接处理掉。

sigchild

在子进程退出时,也会对父进程发送一个信号,这个信号是17.默认对这个信号的处理方式是忽略。

可以通过捕捉这个信号,在收到这个信号时,使用进程等待非阻塞轮询来回收子进程。


http://www.kler.cn/a/415900.html

相关文章:

  • nodejs30: CSS 剪辑路径clip-path导致伪元素不可见问题及解决方法
  • 前端导出文件,下载文件,downloadFile 方法汇总
  • 基于Java的小程序电商商城开源设计源码
  • PostgreSQL在Linux环境下的常用命令总结
  • vue3 发送 axios 请求时没有接受到响应数据
  • 建造者模式Builder——优雅的使用姿势
  • springboot339javaweb的新能源充电系统pf(论文+源码)_kaic
  • nginx同一域名下部署多个项目
  • 【动态规划】股票市场交易策略优化
  • hhdb数据库介绍(10-17)
  • Kylin Server V10 下 Nacos 集群部署
  • KST-3D01型胎儿超声仿真体模、吸声材料以及超声骨密度仪用定量试件介绍
  • 总结UiPath Studio的介绍与安装步骤
  • DETR:End-to-End Object Detection with Transformers
  • Android触摸事件setOnTouchListener用法
  • 各个排序算法基础速通万字介绍
  • STM32--MAP文件
  • 【论文复现】LoRA:大模型的低阶自适用
  • Python-链表数据结构学习(1)
  • 10个Word自动化办公脚本
  • HCIA笔记6--路由基础
  • 信息系统项目管理-论文写作方法之背景二
  • 开源的跨平台SQL 编辑器Beekeeper Studio
  • pdf.js 预览pdf的时候发票数据缺失显示不全:字体加载出错(缺失)导致部分缺失
  • qt QGraphicsPolygonItem详解
  • RVO动态避障技术方案介绍