信号--Signal

本文介绍了信号在操作系统中的作用,以及信号产生的四种方式,包括终端按键、硬件异常、软件条件和调用系统函数。还阐述了信号的三种处理方式:忽略、默认处理和捕捉,并详细说明了信号捕捉的执行流程,即捕捉信号后到内核处理,执行自定义回调函数,再继续原程序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

信号–Signal

信号的作用就相当于神经系统,来帮助操作系统进程运行过程中遇到的各种意外。

Linux系统中通过命令kill -l来查看所有信号。

所有信号预览

信号产生的方式:

1. 通过终端按键产生信号(键盘产生)

最常见的键盘产生的信号:

ctrl + c => 2对应的是2号信号SIGINT

ctrl + z => 19对应的是19号信号SIGSTOP。

ctrl + \ => 3对应的是3号信号SIGQUIT。

2. 硬件异常产生信号

  1. MMU产生信号 => 段错误

    我相信大家对段错误已经很熟悉了,就是越界访问嘛。可是段错误的底层原理到底是什么呢?

    当程序传来一个非法的地址的时候,MMU就先从页表中寻找相对应的物理地址,当MMU没有找到,MMU就会告诉操作系统虚拟地址非法,由操作系统给该进程发送一个11号信号 SIGSEGV 让进程异常终止,引发段错误。

    #include <iostream>
    
    
    int main(void)
    {
        int *p = nullptr;
        *p = 7;
        std::cout << *p << std::endl;
    
        return 0;
    }
    

    在这里插入图片描述

  2. CPU 产生信号 => 除0操作

    CPU是一个强大的运算器,当CPU在运算时遇到了除 0 操作,就会告诉操作系统这是一个除 0 操作,操作系统就会给该进程发送一个 8 号信号 SIGFPE

    #include <iostream>
    
    
    int main(void)
    {
        std::cout << 6 / 0 << std::endl;
    
        return 0;
    }
    

    在这里插入图片描述

3. 软件条件产生信号

  1. assert 表达式如果为假,就会调用abort()函数,abort()函数就会触发6号信号SIGABRT

    #include <iostream>
    #include <cassert>
    
    
    int main(void)
    {
        assert(0);
    
        return 0;
    }
    

    在这里插入图片描述

  2. PIPE读端关闭,如果尝试写,就会触发SIGPIPE信号,管道破裂。出现的时候没有任何征兆,没有提示。

4. 调用系统函数,向进程发送信号

kill命令是调用kill函数实现的。kill函数可以给一个指定的进程发送指定的信号。

raise函数可以给当前进程发送指定的信号。

信号处理方式

  1. 忽略。

    这就表示当接收到信号后,选择忽略这个信号,就是不做任何处理。这是一种不好的处理方式。

  2. 默认处理行为。

    大部分的信号默认处理行为都是结束进程。

  3. 捕捉信号。

    通过自定义的行为来处理信号。

信号捕捉

捕捉信号就是当操作系统给该进程传来一个信号,我们可以通过自己定义的处理方式来处理。

#include <iostream>
#include <cassert>
#include <csignal>


void MyHandler (int signal)
{
    std::cout << "Catch a signal : " << signal << std::endl;
}

int main(void)
{
    signal(SIGINT, MyHandler);
    
    while (1)
    {
        ;
    }

    return 0;
}

在这里插入图片描述

当我通过键盘ctrl + c来触发2号信号的时候,signal系统调用就会捕捉到2号信号,并且对2号信号做出我自定义的行为而不是默认的终止程序了。

那么信号的捕捉到底是怎么执行的呢?

在这里插入图片描述

  • 首先不管程序执行到哪个地方了,当singnal捕捉到了一个信号,就会立刻触发信号。
  • 然后到内核中,根据信号的种类来进行处理。
  • 执行我们自定义的回调函数。
  • 回调函数结束后,会继续到刚才程序执行到的地方的继续执行程序。

叮~ ?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值