【Linux】信号相关知识详细梳理

目录

1. 信号概念

 2. 信号的产生

3. 信号处理

4. 信号原理 

4.1 理解信号行为

4.2 重谈信号产生

4.3 信号保存

4.3.1 信号集

4.3.2 信号集操作函数

4.4 信号处理

4.4.1 信号捕捉和处理


1. 信号概念

        在 Linux 系统中,信号是一种用于进程间通信 (IPC) 的机制,可以用来通知进程发生了某些事件。信号是由内核或进程发送的,目标是终止、暂停、恢复或触发特定行为。

        

  • 信号 (Signal) 是一种软件中断,用于通知进程需要执行某种特定的处理。
  • 信号的来源可以是用户、内核或者其他进程。
  • 每个信号都有一个唯一的编号和对应的符号名称(例如,SIGKILL 对应编号为 9)。

以下是一张信号表,可用 kill -l 命令查看:

 2. 信号的产生

        在讲信号的产生前,首先看一个信号的例子:

        以下程序是一个捕捉信号 SIGINT (编号9),并执行对应的信号处理方法的程序,代码如下:

#include <stdio.h>
#include <signal.h>

//信号处理方法
void sigcb(int signum)
{
    printf("signum is %d\n",signum);
}

int main()
{
    //设置要捕捉的信号,和信号处理方法
    signal(SIGINT,sigcb);
    while(1)
    {}
    return 0;
}

        我们都知道 按住 ctrl + c可用终止一个进程的运行,实际上ctrl + c的原理就是向进程发送SIGINT信号,该信号的默认处理方式就是终止程序,而我们设置了信号处理方法后,不再用默认方式处理信号,于是现象如下:

        可以看到,对应进程在接收到SIGINT后,执行了我们设置的处理方法,其中ctrl + c就是一种产生信号的方式,接下来在看看其他方式。

        kill命令:

kill [选项] 信号 [PID...]
  • 信号:可以是信号的名称(如 SIGTERM)、编号(如 15),或前缀省略的简写(如 TERM)。
  • PID:目标进程的 ID(进程号),也可以是多个 PID。

例如:

# 向进程1234发信号SIGKILL信号的不同方式:

kill -SIGKILL 1234   # 使用信号名称
kill -9 1234         # 使用信号编号
kill -KILL 1234      # 使用简写

现象示例:

3. 信号处理

        对于一个信号的处理,有三种方式:

1. 忽略此信号

#include <iostream>

#include <unistd.h>
#include <signal.h>
void handler(int signumber)
{
std::cout << "我是: " << getpid() << ", 我获得了⼀个信号: " << signumber
<< std::endl;
} i
nt main()
{
std::cout << "我是进程: " << getpid() << std::endl;
signal(SIGINT/*2*/, SIG_IGN); // 设置忽略信号的宏
while(true){
std::cout << "I am a process, I am waiting signal!" << std::endl;
sleep(1);
}
} 
$ g++ sig.cc -o sig
$ ./sig
// 现象:
// 我是进程: 212681
// I am a process, I am waiting signal!
// I am a process, I am waiting signal!
// ^C^C^C^C^C^CI am a process, I am waiting signal! // 输⼊ctrl+c毫⽆反应
// I am a process, I am waiting signal!

2. 执行该信号的默认处理动作

#include <iostream>
#include <unistd.h>
#include <signal.h>
void handler(int signumber)
{
    std::cout << "我是: " << getpid() << ", 我获得了⼀个信号: " << signumber<< std::endl;
} 
int main()
{
    std::cout << "我是进程: " << getpid() << std::endl;
    signal(SIGINT/*2*/, SIG_DFL);
    while(true){
    std::cout << "I am a process, I am waiting signal!" << std::endl;
    sleep(1);
    }
} 
$ g++ sig.cc -o sig
$ ./sig
// 我是进程: 212791
// I am a process, I am waiting signal!
// I am
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值