Linux信号处理

每个信号名都以SIG开头,信号名的定义都在头文件<signal.h>中,通过kill -l 命令可查看信号:

        信号名一般都是宏,内部通常是一个正整数(信号前面的数字表示), 信号(signal)它是一种软件中断,它提供了一种处理异步事件的方法,在Linux中没有32号信号和33号信号,34以前的为普通信号(不可靠信号),34以后的为实时信号(可靠信号),如果信号一旦产生,可能不会立即处理它,等待合适的时间才去处理,信号事件的产生对进程而言是异步的,信号如果无法对它进行处理,就先将它记录下来,处理信号的三种方式执行确认/默认动作、忽略信号、自定义的动作(捕捉)


信号的本质
        操作系统给进程发送信号,本质上是给进程的PCB中写入数据,修改相应的PCB字段,进程在合适的时间去处理所接受的信号: 

1)用户输入一个命令,在shell下启动一个前台进程。
2)用户按下ctrl+c,通过键盘输入产生了一个硬件中断。
3)如果CPU当前正在运行此进程的代码,则该进程的用户空间代码暂停执行,CPU从用户态切换        到内核态处理中断。
4)终端驱动程序将ctrl+c解释为一个SIGINT信号,记在该进程的PCB中。
5)当某个时刻从内核返回该进程的用户空间代码继续执行之前,首先处理PCB中记录的信号。SIGINT信号默认处理动作为终止信号,所以直接终止进程而不再返回到它的用户空间代码。

引发信号的情况
        1.键盘事件 ctrl +c (ctrl+c所产生的信号只能发送给前台进程(当前终端))
        2.非法内存 如果内存管理出错,系统就会发送一个信号进行处理
        3.硬件故障 同样的,硬件出现故障系统也会产生一个信号
        4.环境切换 比如说从用户态切换到其他态,状态的改变也会发送一个信号,这个信号会告知             给系统
信号的来源
        1、程序的错误,如非法访问内存
        2、外部信号,如按下了CTRL+C
        3、通过kill或sigqueue向另一个进程发送信号(常用)
        进程可以屏蔽掉大多数的信号,除了SIGSTOP和SIGKILL
        SIGSTOP:使正在运行的进程暂停
        SIGKILL:使正在运行的进程退出
信号的优先级
        信号实质上是软中断,中断有优先级,信号也有优先级。
        如果一个进程有多个未决信号,则对于同一个未决的实时信号,内核将按照发送的顺序来递                   送信号。
        如果存在多个未决信号,则值(或者说编号)越小的越先被递送。
        如果即存在不可靠信号,又存在可靠信号,虽然POSIX对这一情况没有明确规定,但Linux系                 统和大多数遵循POSIX标准的操作系统一 样,将优先递送不可靠信号。



 man signal:

#include<signal.h>
typedef void (*sighandler)(int);//函数指针
sighandler signal(int signum,sighandler handler);
signum :需要处理的信号编号
sighandler :信号的处理函数
SIG_IGN :忽略该信号
SIG_DFL :使用默认的信号处理函数(方式)

SIGINT信号的捕捉(2号)

#include<iostream>
#include<signal.h>
#include<unistd.h>
using namespace std;
int main()
{
    signal(2,SIG_IGN);   //也可以写信号 SIGINT,SIG_IGN 表示忽略该信号
    while(1)
    {
        cout<<"2"<<endl;
        sleep(1);
    }
    return 0;
}

当输出 ctrl+c 时并不会中断程序,因为 SIG_IGN 忽略了,程序继续执行,需要通过kill -9 pid来杀死该进程。

 


//SIG_DFL
#include<iostream>
#include<signal.h>
#include<unistd.h>
using namespace std;
int main()
{
    signal(2,SIG_DFL);      //SIG_DFL 表示恢复对信号的系统默认处理,注释掉这行也跟没注释一样(也是执行系统默认的操作)
    while (1) 
    {
        cout<<"2"<<endl;
        sleep(1);
    }
    return 0;
}

ctrl+c 被执行

信号 SIGKILL 和 SIGSTOP 无法被捕获或忽略,signal(9,SIG_IGN),kill -9 pid 被执行(19号同理):

 
 

      SIG_DFL 和 SIG_IGN:

 reference:

         https://blog.csdn.net/qq_41035588/article/details/83787122

         https://blog.csdn.net/weixin_45407386/article/details/102550816

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值