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

Linux进程信号保存/操作系统运行原理

知识补充:

系统调用:pause(); 该函数可以等待发出信号

signal:可以进行信号捕捉

其中,信号捕捉分为三点:

1,默认

2,忽略

3,自定义

默认和忽略系统中给我们提供了具体调用方法:

默认:SIG_DFL

自定义:SIG_IGN

信号相关的其他概念

1,实际执行信号的处理动作称为信号递达

2,信号从产生到递达之间的状态叫做信号未决

3,进程可以选择阻塞某个信号

(信号产生之后会对阻塞的目标信号进行pending,永远不递达,除非我们解除阻塞)

4,被阻塞的信号产生时会一直处于未决状态,直到解除阻塞状态,信号才能执行递达的动作。

5,注意,忽略和阻塞是不同的,只要信号被阻塞就不会被递达,而忽略是递达之后可选的一种处理动作。

进程如何完成进程保存的

在task_struct中维护着三张表,分别叫block,pending,handler

pending

pending表本质就是位图(1-31)

含义:

1,比特位位置代表信号编号。

2,比特位内容 0/1 代表是否收到对应的信号。

pending位图就是当前进程收到的信号列表

handler

handler表本质其实是一个函数指针列表,信号编号-1就是函数指针数组的下标

所以,signal(2,handler)中2就是去找下标,handler就是去修改数组内的内容

这也就是为什么signal改一次之后,后面的内容都会变成自定义内容。

block

block表其实本质也是一张位图,也是维护1-31的内容

含义:

1,比特位位置代表信号编号

2,比特位内容0/1代表是否阻塞,屏蔽特定信号,决定了pending是否可以访问handler表。

我们可以提前屏蔽,屏蔽课收到信号两者毫无关系。

所以,要看某个信号是否要被处理,我们可以横着看:

如果block里值为1,pending值为1,就不递达

如果block里值为零,pending值为0,也不做处理

如果block里值为0,pending值为1,就会对信号进行处理:

信号集操作函数

sigset_t

这是系统封装的pending/block的数据类型,可对其内容进行改变,但是修改内容涉及位图的操作,容易产生失误,所以系统也提供了余其他函数来对sigset_t进行操作:

sigemptyset:可以将位图初始化为全0

sigfillset:可以将位初始化为全1

sigaddset:可以将signum信号添加到set中

sigdelset:可以将特定信号删除

sigismember:可以判断signum信号是否在set里

sigprocmask

该函数可以读或者该进程信号的屏蔽字:

其中,how代表用什么方式进行修改,系统提供了三种函数来供我们使用:

其中第三个参数是可以拷贝一份老的数据出来做备份的。

sigpending

sigpending的参数属于输出型参数,可以获取pending信号集

代码演示

接下来将用代码的方式来混用上面的函数,以便大家理解:

1,对2号信号进行屏蔽

2,如何获取pending表

3,如何解除屏蔽?

可以使用之前备份的oblock来进行备份:

代码如下:

可以看到,当我们解除了二号信号屏蔽,系统就会执行二号信号,二号信号默认行为是退出,如何我们没对信号进行捕捉,所以进程就会退出。

信号捕捉

在主函数因为中断,异常或系统调用将进入内核处理,处理完后可以递送的信号,字给到信号处理,如果信号处理为忽略或者默认就回到主流程,如果是自定义就会调用用户自定义函数,如何在进到内核流程中被中断的地方继续执行。

os运行状态

1,用户态---我自己写的代码

2,内核态---执行os代码

所以信号捕捉流程:

os是怎么运行的

1,硬件中断

在图中左侧有各种各样的外设,当他们的内容准备就绪时,就会通知中断控制器,通知cpu,cpu知道中断之后会回来获取中断号,如何去os根据中断号在中断向量表中找对应的方法并执行,当执行完毕之后会恢复现场并持续刚刚的工作。

2,时钟中断

此中断会一直推进os的调度,在当代设备中,有一个时钟源会一直给os发送时钟中断,而这个时钟源现在在cpu中,如果在外设的话就太慢了,而时钟源发送的频率称为主频,主频越高代表cpu利用效率越高,调用os的次数就越多,cpu也越贵。

此时我们知道,os是基于中断向量表工作的,cpu中时钟源会不断地推进os的运行

os这样就可以之间躺平,要什么就去向量表拿。

3,软件中断

除了上面说的硬件中断,还有软件中断,cpu用和汇编可以让cpu内部促发中断逻辑

4,什么是时间片?

就是时钟中断时固定的发过来:1纳秒

task_struct

{

int count = 1000;

count--;

if(count == 0);---

}

时间片本质就是一个计数器,当count==0时,就进行进程切换。

内核页表

一个进程中除了有用户页表,也有一个内核页表:

在每一个进程中,用户页表每个进程互不影响,相互独立,但是在所有进程中,内核页表整个系统就只有一个,所以无论进程怎么调用调度,都能找到同一个os。


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

相关文章:

  • Mongo数据库 --- Mongo Pipeline
  • C嘎嘎探索篇:栈与队列的交响:C++中的结构艺术
  • Elasticsearch面试内容整理-常见问题和解决方案
  • 一个高度可扩展的 Golang ORM 库【GORM】
  • 深度学习——3种常见的Transformer位置编码【sin/cos、基于频率的二维位置编码(2D Frequency Embeddings)、RoPE】
  • BERT的中文问答系统42
  • 【第三讲】Spring Boot 3.4.0 新特性详解:增强的配置属性支持
  • 无人机:智能航点规划技术!
  • jQuery-Json-AJAX-跨域
  • 【前端】javaScript
  • Excel与PPT:职场两大软件的应用比拼
  • 调用 AWS Lambda 时如何传送字节数组
  • 关于IDE的相关知识之三【插件安装、配置及推荐的意义】
  • Python语法基础(一)
  • 【C++】C++的nullptr和NULL
  • vue的理解
  • 鸿蒙学习自由流转与分布式运行环境-价值与架构定义(1)
  • 【C++】顺序容器(二):顺序容器操作
  • C++11新特性探索:Lambda表达式与函数包装器的实用指南
  • 极狐GitLab 17.6 正式发布几十项与 DevSecOps 相关的功能【四】
  • STM32中I2C总线中,允许从机控制SCL总线吗?
  • uname -m(machine) 命令用于显示当前系统的机器硬件架构(Unix Name)
  • 什么是 C++ 中的多继承?它有哪些优缺点?什么是虚继承?为什么要使用虚继承?
  • OSPTrack:一个包含多个生态系统中软件包执行时生成的静态和动态特征的标记数据集,用于识别开源软件中的恶意行为。
  • Linux 网络编程之UDP套接字
  • win10中使用ffmpeg的filter滤镜