news 2026/4/18 8:31:59

OS——信号

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OS——信号

目录

信号是什么

信号的类型

信号的产生

两种方式

发送信号的系统调用

关于定时器

信号的保存和信号处理

理清概念

信号处理的时机

修改block表的系统调用

获取pending位图

修改handler数组

不可屏蔽的信号

core和term


信号是什么

我们都知道,OS中很大一部分是靠中断(不管是硬件中断还是软中断)运行起来的,所以早期操作系统又叫做中断处理程序
而信号的机制是与中断类似的一种通知机制,分为产生信号(产生中断),保存信号(保存中断),处理信号(中断处理)个步骤。


信号的类型


信号的产生

两种方式

  • 硬件触发。例如:我们点击键盘的“ctrl + c”会首先触发中断,然后调用中断处理例程,在其内部判断到时这个组合键之后就会给当前的前台进程发送死亡信号,终止前台进程。
  • 软件触发。我们可以通过系统调用来发送信号;或者在OS中创建定时任务,由定时任务发送信号;也可以在命令行中输入发送信号的命令(kill);再比如管道写时如果读不具备就会给写的进程发送终止信号

发送信号的系统调用

//给进程号为pid的进程发送sig信号 #include <sys/types.h> #include <signal.h> int kill(pid_t pid, int sig); //调用它的进程给自己发送sig信号 #include <signal.h> int raise(int sig); //给本进程发送SIGABRT信号,杀死自己 #include <stdlib.h> void abort(void); //在seconds秒之后给调用alarm的进程发送SIGALRM信号,SIGALRM信号的默认处理方式是杀死进程 #include <unistd.h> unsigned int alarm(unsigned int seconds);//如果在前一个alarm没有起作用前再一次调用它,则重置倒计时并返回上一个闹钟剩余的秒数,alarm(0)意思是取消所设的闹钟。

关于定时器

其实每一个定时器就是OS内部的数据结构,所有的定时器被组织成对应的数据结构,OS依靠硬件进行计时,到了过期时间就执行定时器内部绑定的回调方法。而alarm函数就是告诉OS:给我创建一个定时器,这个定时器的任务是给当前进程发送SIGALARM信号。进程收到信号就会执行信号处理函数(默认杀死自己)。


信号的保存和信号处理

理清概念

信号的发送和程序的执行是异步的,因此在我们发送信号给进程后,进程可能正在执行其他指令,而且在一些情况下(比如IO),这种指令是不可以被打断的,所以进程必须有暂时保存信号的能力。话不多说,信号是保存在进程PCB里面的位图中的,信号的处理函数也是保存在PCB中的,除此之外PCB中还有表示屏蔽某信号的位图。如下图:

  • 信号被发送给进程之后,将pending位图相应位置置1,pending位图中就存放着所有进程收到的信号,这就是发送信号的本质。
  • 如果信号没有被处理,pending相应位置就会一直为1。在这次信号被处理之前发送多个信号是无效的。
  • 进程想要阻塞某信号就把block位图相应位置置1。即使阻塞了某信号,进程也会把收到的某信号存放在pending中,一但运行过程中取消阻塞,曾经被阻塞的信号还会被处理。
  • 进程会在合适的时机查看pending表,如果发现某信号对应的位置为1并且block中对应的位置为0,就执行对应的信号处理函数,而这些默认的信号处理函数的函数指针被存放在handler数组中,可以把信号编号当作下标取出对应的函数指针并执行,然后把pending表相应位置置0,表示信号被处理完了。这就是信号处理的本质。
  • 进程PCB在创建之时默认初始化handler数组,所以我们发送的信号都有其对应的默认处理方法,SIG_IGN表示忽略该信号。我们可以使用系统调用来修改某信号对应的信号处理函数,也就是修改handler表,让进程用我们定义的函数来处理相应信号。

术语:某信号在pending中时叫做信号未决,信号被处理叫做信号递达,自定义信号处理函数叫做信号捕捉

信号处理的时机

内核处理完异常或者执行完系统调用后,要返回用户态之前,会处理当前进程的PCB中的pending中的信号,这就是信号处理的时机。自定义信号的处理流程如下:

为什么要从内核返回用户才可以执行信号处理函数,内核态权限不是更高吗?

  • 如果信号处理函数中有访问操作系统的代码,那么就可以利用内核态的权限直接对操作系统做任何事,这样很危险,所以要把内核态转回用户态才可以执行函数。

为什么函数执行后不直接返回main函数而是要先返回内核态

  • 无法返回,main函数和signal处理函数无调用关系,无法直接返回,而do_signal()和main函数有调用关系。

如果是非自定义信号的处理函数,会直接在内核态执行,执行结束后直接返回用户态的main函数中。

修改block表的系统调用

获取pending位图

修改handler数组

注:如果我们是自定义信号处理函数的话,在函数内部可能再次陷入系统调用,如果此时再次到来相同的信号就又会调用相同的信号处理函数.....如果一直发送该信号的话就会导致栈溢出,而sa_mask可以设置执行自定义信号处理函数时要屏蔽的信号(比如说屏蔽当前正在处理的信号,就不会调用两次同一个处理函数了),防止上面的情况出现


不可屏蔽的信号

如果所有的信号都是可以屏蔽的,那么一个进程运行起来屏蔽所有信号,他就可以一直运行下去,不会被杀死,因此在OS,一些信号比如9号信号(终止进程)不能被屏蔽(也不能被自定义信号处理函数)


core和term

SIGQUIT和SIGINT的都是进程退出信号但是他们一个是core终止,一个是term终止,前者是异常终止进程,后者是正常终止进程。

如果开启了对应功能,core发生后就会在进程当前工作目录生成core文件,保存错误,gdb可以用这个文件快速定位发生异常的位置。而云服务器一般是关闭core文件生成功能,防止core文件把磁盘打满。

利用core文件的方法如下

core和进程等待的关系

父进程等待子进程结束后会获取到子进程的结束信息,这个里面就有一个core标志位。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 8:31:22

八大网盘直链下载神器:LinkSwift技术解析与实战指南

八大网盘直链下载神器&#xff1a;LinkSwift技术解析与实战指南 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 &#xff0c;支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云…

作者头像 李华
网站建设 2026/4/18 8:25:16

JavaScript 异步编程

JavaScript 异步编程学习笔记 JavaScript 是单线程语言&#xff0c;这意味着它同一时间只能执行一段代码。为了解决耗时操作&#xff08;如网络请求、文件读写、定时器&#xff09;阻塞主线程的问题&#xff0c;JavaScript 发展出了强大的异步编程模型。1. 核心概念概念说明同步…

作者头像 李华
网站建设 2026/4/18 8:24:43

java——接口——非抽象方法

文章目录背景Java 接口与抽象类详解一、接口实现与部分实现的问题问题描述答案解决方案关键概念区分类型对比表二、接口中的 default 方法(第一次见到)问题描述答案接口方法的完整规则&#xff08;Java 8&#xff09;为什么引入 default 方法&#xff1f;完整示例三、接口与抽象…

作者头像 李华
网站建设 2026/4/18 8:23:12

AMD Ryzen 硬件调试实战:从零掌握SMUDebugTool的精准控制系统

AMD Ryzen 硬件调试实战&#xff1a;从零掌握SMUDebugTool的精准控制系统 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: htt…

作者头像 李华
网站建设 2026/4/18 8:21:02

WebPlotDigitizer:如何快速从科研图表中提取数据的终极指南

WebPlotDigitizer&#xff1a;如何快速从科研图表中提取数据的终极指南 【免费下载链接】WebPlotDigitizer Computer vision assisted tool to extract numerical data from plot images. 项目地址: https://gitcode.com/gh_mirrors/we/WebPlotDigitizer 在科研工作中&a…

作者头像 李华
网站建设 2026/4/18 8:20:42

解决Tkinter和Matplotlib的无限循环问题

在使用Python进行图形界面编程时,经常会遇到将Matplotlib的图表嵌入到Tkinter窗口中的需求。然而,这个过程中可能会遇到一些棘手的问题,比如程序进入无限循环,导致无法正常结束进程。今天我们就来详细讨论一下这个问题,并通过实例展示如何解决。 问题背景 在编写Tkinter…

作者头像 李华