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

【Linux】信号

目录

信号的概念

信号的产生

键盘组合键

指令

系统调用

kill

raise

abort

硬件异常

软件条件

core dump

信号的发送

信号的保存

概念

三张表

接口

sigset_t

信号集操作函数

sigprocmask

sigpending

代码示例

信号的捕捉处理

内核态与用户态

内核空间

捕捉信号

signal

sigaction

可重入函数

volatile

SIGCHLD信号


信号的概念

前台进程

ctrl c 是2号信号

给信号设置自定义动作

键盘输入数据完成后,会通过硬件中断提醒CPU,操作系统提取对应中断号去中断向量表执行对应方法。

异步


信号的产生

键盘组合键

键盘输入完成后,给CPU对应针脚发送硬件中断,操作系统会根据中断号在中断向量表中找到对应中断方法并执行,把键盘上的数据读到内核里,识别到是组合键,就把组合键转成对应信号发送给目标进程。


指令


系统调用

kill

第一个参数是进程,第二个参数是信号

raise

谁调用你,你就对谁发送信号

abort

给自己发送6号信号。

正常来说,如果你对6号信号进行了自定义行为,那么当你接收到6号信号时,你就会做自定义行为。

但这个函数不是,它会先执行自定义行为然后中止进程。


硬件异常

除0错误会收到8号信号

野指针异常会收到11号信号

当出现除0,野指针这些错误时操作系统会给进程发送信号,这些信号的默认动作是中止进程。

操作系统怎么知道有除0错误的?

因为CPU有状态寄存器会识别并告诉操作系统

操作系统怎么知道野指针错误的?

MMU是内存管理单位,集成在CPU中。

CPU读到的虚拟地址结合页表和MMU去转化物理地址,野指针就是地址转化失败,CPU有个寄存器会保存转化失败的地址,转化失败会出现硬件报错被操作系统识别。

操作系统怎么知道你是除0错误还是野指针错误?

因为是不同的寄存器,不同的硬件报错。

上述的异常在对信号进行捕捉时会出现死循环,是因为硬件方便一直报错,无论被调度多少次,每当你带着上下文回来,操作系统就会检测到你的硬件报错。


软件条件

管道写端一直在写,但读端不读了,系统就会给写端进程发送信号关闭进程。

闹钟

返回值是上一个闹钟剩余时间。


core dump

core dump标志保存你的中止方式,是Core还是Term,Term是0,Core是1。

当前目录下生成了core文件。

打开core dump功能并且是Core行为的信号就会触发核心转储。

为什么要进行核心转储?

调试可以直接把core文件导进来,可以直接定位到出错原因。

云服务器的Core功能默认关闭,因为自动重启功能可能会导致磁盘被core文件打满。

设置大小开启


信号的发送

本质是写信号,在PCB中的位图管理。

为什么必须是操作系统发?


信号的保存

概念


三张表

pending表保存着接收的信号,这些信号还没执行对应方法。

handler表是函数指针数组,保存着信号默认方法,如果用户要自定义方法,就是用signal函数把用户提供的方法替换进来。

block表记录对应信号是否被屏蔽,1是屏蔽。

默认处理动作其实是整数,只不过被强转成函数指针类型。


接口

sigset_t

这是信号集类型,本质是位图,接下来进行信号位图交流时都要用这种类型。

信号集操作函数


sigprocmask

第一个参数

第二个参数是我们设置一个信号集去和系统的信号集交互。

第三个参数是输出型参数,我们找个地方存放老的信号集。


sigpending

输出型参数,把pending表带出来


代码示例

//测试:练习使用操作信号集的接口,以及操作block表和pending表的接口

#include <iostream>
#include <unistd.h>
#include <signal.h>

using namespace std;

//捕捉后的自定义动作
void MyHandler(int signo)
{
    cout << "get signal: " << signo << endl;
}

void PrintPending(const sigset_t& pset)
{
    for(int i=31; i>=1; i--)
    {
        if(sigismember(&pset, i))
        {
            cout << "1";
        }
        else
        {
            cout << "0";
        }
    }
    cout << endl;
}

int main()
{
    //对测试信号进行自定义捕捉
    signal(2, MyHandler);

    //构建信号集
    sigset_t set, oset;
    sigemptyset(&set); //全0
    sigemptyset(&oset);
    sigaddset(&set, 2); //对2号信号置1

    //通过sigprocmask把信号集设置进内核
    sigprocmask(SIG_BLOCK, &set, &oset);

    //通过sigpending观察pending表
    int cnt = 0;
    while(1)
    {
        sigset_t pset;
        sigemptyset(&pset);
        sigpending(&pset); //获取pending表

        PrintPending(pset); //打印pending表
        sleep(1);

        if(cnt == 10) //解除阻塞
        {
            sigprocmask(SIG_SETMASK, &oset, nullptr);
        }
        cnt++;
    }

    return 0;
}

信号的捕捉处理

内核态与用户态

信号是什么时候被处理的?

内核态与用户态切换

操作系统怎么判断当前是内核态还是用户态?

CPU有一个ecs寄存器,其中有两个比特位来记录,00(0)是内核态,11(3)是用户态,使用int80陷入内核就可以把3变成0,该进程就变成内核态可以访问内核空间了。

当进程遇到系统调用等原因,会从用户态变成内核态完成对应任务。

完成任务后会变回用户态,在变回之前会检测信号。

先看pending表,再看block表,如果有信号且未阻塞再看处理方法,默认就直接中止进程,忽略就直接返回用户态。

如果是用户自定义方法,就暂时变成用户态完成对应任务,然后变回内核态,然后按照流程处理完信号后就变回用户态。

进程是会被调度的,因为时间片,所以会周期性的态变换,尽管没有系统调用之类的。


内核空间

时钟中断

操作系统是一个死循环,有一个硬件是时钟芯片,每隔一段时间就会给系统发一个中断,系统就会检查当前进程的时间片使用情况,均匀的持续的推着操作系统运作。


捕捉信号

signal


 

sigaction

第一个参数是信号编号

结构体第一个字段是处理方法

sa_mask字段是设置你额外还想屏蔽的信号,除了系统自动屏蔽当前正在处理的信号。


可重入函数

函数进行到一半,进程切换了,由于态转换又触发了信号的处理。


volatile

main函数中,CPU对flag变量并没有修改行为只有检测行为,可能会导致flag变量的值直接存到寄存器中,以后CPU就不访问内存了直接访问寄存器。

-O是选择优化模式

volatile防止被优化


SIGCHLD信号

如果多个同时退出就用循环等待,因为有部分退出的情况,所以采用非阻塞等待,防止卡在那里。

父进程中,把SIGCHLD信号的处理动作设置成忽略,可以让子进程退出时不会产生僵尸进程,父进程也不关心子进程退出情况。

手册的忽略和显式忽略不一样。

相关文章:

  • 图片查看器:用PyQt5实现本地图片预览工具
  • 使用AOP + Prometheus + node-exporter + grafana 实现Java系统的接口监控
  • 【自动化】Automa网页自动化之路
  • ⭐算法OJ⭐链表排序【归并排序】(C++/JavaScript 实现)
  • ChatGPT辅助学术写作有哪些挑战?怎么解决?
  • 11 应用层的域名知识点
  • Application.OnTime如何引用带参数的过程
  • 【Hive】Hive安装
  • 网络安全基础与应用习题 网络安全基础答案
  • 解决电脑问题(7)——软件问题
  • Android中使用Glide加载图片闪烁问题
  • Transformer原理硬核解析:Self-Attention与位置编码
  • 算法优选系列(1.双指针_下)
  • Python Flask 构建REST API 简介
  • Linux 进程信号
  • 文件包含漏洞第一关
  • llvm数据流分析
  • 【数据结构】2算法及分析
  • Android 粘包与丢包处理工具类:支持多种粘包策略的 Helper 实现
  • 灰度发布和方法灰度实践探索
  • 长三角铁路今日预计发送386万人次,沪宁、沪杭等方向尚有余票
  • 新加坡执政党人民行动党在2025年大选中获胜
  • 人民日报评论员:把造福人民作为根本价值取向
  • 国家卫健委对近日肖某引发舆情问题开展调查
  • 夜读丨春天要去动物园
  • 俄伏尔加格勒机场正式更名为斯大林格勒机场