【Linux】进程信号(上)(一)

简介: 【Linux】进程信号(上)

1.信号概念理解

信号产生

什么叫做信号呢?

生活当中认为是信号的是:红绿灯 闹钟 下课铃 鸡叫 手势

1.当红灯亮的时候, 你会停下来 即匹配的动作

那为什么会有这个匹配动作呢?

因为曾经有人培养过你

所以信号没有被产生,也知道怎么该处理它


2.我们能够认识并处理一个信号,是能因为识别这个信号的


若进程就是我,信号就是一个数字,进程在没有接收信号的时候,它早就知道一个信号该如何处理了

程序员在设计进程的时候,早就已经设计了对信号的识别能力


3.因为信号可能随时产生,所以在信号产生前,我可能正在做优先级更高的事情,我可能不能立马处理信号

要在后续合适的时候进行处理


如:你点了一份外卖,因为你不确定外卖什么时候到,所以开了一把游戏,当外卖小哥给你打电话说外卖到了时,游戏还没打完,所以你跟外卖小哥说等一会,马上到,然后继续打游戏,直到游戏打完,才去取外卖


信号保存


4a18d0e8648c4c058e394f50fbc0031f.png

在信号产生和信号处理之间,存在时间窗口,因为没办法直接处理,需要等待后续处理

在时间窗口期间,需要被保存起来


进程收到信号的时候,如果没有立马处理这个信号,需要进程具有记录信号的能力


信号的产生对于进程来讲是异步的


异步为两者互相做自己的事,互不干扰

如:你正在上课,外卖小哥给你打电话告诉你快递到了,因为快递有重要的东西,所以你不得不现在去取,但是在你取快递的过程中,依旧在上课,上课与你取快递两件事情互不干扰


进程该如何记录对应产生的信号?记录在哪里?


可能同时收到很多信号,已经被产生但尚未处理,所以需要在时间窗口内,将这些信号保存,同时也应该将其进行管理

而管理的本质是先描述,在组织

那如何描述一个信号呢? 用什么数据结构管理这个信号呢?


输入 kill -l 查看信号列表


7845a99154624b22b53ba3cf89376d17.png

可以发现在31 和34之间没有信号存在,说明信号被划分为两部分,1-31以及34-64

34-64称之为实时信号,

1-31称之为普通信号,是目前要学习的信号

数字实际上是真正的信号,而大写的名称是宏


实时操作系统

当前主流的操作系统分为实时和分时,

分时像Linux、windows操作系统,基于时间片操作器调度的,强调的是公平调度

实时 像汽车的车载系统的辅助驾驶

特点为若来一个任务,就必须优先级较高的将该任务立马处理,强调的是高响应

普通信号 ,只保存有无产生,只需在合适的时候处理信号即可


可以通过0代表没有产生,1代表产生

1-31刚好是32个比特位,所以使用位图结构管理信号

而进程使用task_struct(PCB) 内部必定要存在一个位图结构,用int表示


e775d28d82ab45da82ba18967f920850.png


从低到高的比特位,依次对应1-31 信号

发送信号的本质是写入信号,直接修改特定进程的信号位图中的特定比特位,0变成1即可

比特位的位置,称之为信号的编号

比特位的内容,表示是否收到该信号


信号处理

默认处理信号的方式:

1.默认动作

2.忽略信号

3.用户自定义动作

如:拿到快递,共有三种选择

1.执行默认动作把快递打开 2.忽略快递 3. 执行自定义动作(如快递内是零食,送给你的女朋友)

2. 信号的产生

在vscode中,创建makefile文件

mysignal:mysignal.cc
    g++ -o $@ $^
.PHONY:clean
clean:
    rm -f mysignal

创建 mysignal.cc(以cc结尾是cpp) 文件

会一直循环打印一句话,并当前进程的包含pid值

#include<iostream>
#include<unistd.h>
using namespace std;
int main()
{
   while(true)
   {
    cout<<"我是一个进程,我正在运行...,pid值:"<<getpid()<<endl;
    sleep(1);
   }
    return 0;
}

复制SSH渠道创建终端2,在保证运行终端1的可执行程序的情况下,

在终端2中输入 kill -9 +pid值 ,终止了终端1中运行的程序

9b4b44332c1f42a79e378d5f248f36a5.png


8a69448be7cd4f988d64ed882b076810.png


实际上 在键盘中输入 CTRL C ,终止运行程序,本质也是向对前台进程发送信号


2dbb85a1a0c841429f8c8e36cb6ca8ac.png


Linux通过远程终端访问时,只允许一个进程处于前台,默认情况是bash,

所以在自己的程序运行时输入指令没有任何反应


证明输入 CTRL C 就是向前台进程发送信号

输入 man 2 signal 指令


82e0a96dcaac4402a4f0e9fd513d8caa.png


第二个是一个函数指针 将 void(*) (int) typedef 命名为 sighandler_t

signal 函数的第一个参数 是 signsum 代表信号编号

第二个参数 是 handler 代表哪一个进程调用了signal,使指定信号不在执行默认动作,而是执行该函数指针指向的方法


输入 CTRL C 相当于发送 2号信号


修改 mysignal.cc文件内容,并运行程序 发现输入 CTRL C 指令无法结束程序


77dc6362ec1d40f7ac58ef211a390ddb.png

91444f691e8f400298b8aedf8468f0dd.png

同样在终端2中输入 kill -2 pid值,也无法结束运行程序

说明对于2号信号 ,进程的默认方法是终止进程

signal 可以进行对指定动作的信号设定自定义处理动作

signal 函数内部参数传递的理解


76facb1bf7794bf0ba3eed8ebe3be66c.png

当signal(2,handler)调用完这个函数时, handler方法没有被调用,只是发生了回调

handler作为函数的地址传过去 作为参数被函数指针接收,再通过函数指针找到handler函数 完成调用

在操作系统内部,把对应的自定义方法的地址保存起来了


handler方法什么时候被调用?

当2号信号产生的时候

如: 你小时候总喜欢在家里调皮,你老爸不管你,认为这是很正常的事情,所以你认为这是默认动作,但是你的老妈看见你调皮,就告诉你说如果下次再看见你调皮,就揍你,

所以再有调皮捣蛋事情发生,不会像你老爸那样什么都不管,你老妈会揍你

是在下次调皮发生的时候,才揍你


对于信号自定义动作的捕捉问题

默认对2号信号的处理动作:终止进程

输入 man 7 signal 指令

f544f273fefa4d019f1c072dd60c83cf.png

2号信号的动作是 Term(终止)

用signal(2,handler),是在执行用户动作的自定义捕捉


878ff5b58f9f4f7ba701282aff92ad73.png


CTRL \ 代表3号信号 ,此时虽然2号信号被置为自定义动作了,但是三号信号还没有,所以依旧能终止进程


修改mysignal.cc文件内容,加入对于3号信号的自定义动作


48a1dacbcb8b41419f3a61d69d18c61f.png

89a3e6623761443482158a12e81eb96f.png


再次运行可执行程序时,发现使用CTRL \ 也会调用自定义动作


77c71f72cb314752af5caf0e0f2c856c.png


可以给所有信号设置同一个处理函数


若修改mysignal.cc文件内容,将1-31的所有普通信号都进行自定义动作捕捉

9dc39ce952ef4734b12af33213ef6529.png


15976f75b1a84035b374efbd14fe60ba.png


可当运行可执行程序时,在终端2中使用 kill -9 pid值 方式依旧可以干掉进程


9号信号被称为管理员信号,不可被自定义,只能执行默认动作


相关文章
|
21天前
|
算法 Linux 调度
深入理解Linux操作系统的进程管理
本文旨在探讨Linux操作系统中的进程管理机制,包括进程的创建、执行、调度和终止等环节。通过对Linux内核中相关模块的分析,揭示其高效的进程管理策略,为开发者提供优化程序性能和资源利用率的参考。
47 1
|
9天前
|
存储 监控 Linux
嵌入式Linux系统编程 — 5.3 times、clock函数获取进程时间
在嵌入式Linux系统编程中,`times`和 `clock`函数是获取进程时间的两个重要工具。`times`函数提供了更详细的进程和子进程时间信息,而 `clock`函数则提供了更简单的处理器时间获取方法。根据具体需求选择合适的函数,可以更有效地进行性能分析和资源管理。通过本文的介绍,希望能帮助您更好地理解和使用这两个函数,提高嵌入式系统编程的效率和效果。
62 13
|
16天前
|
SQL 运维 监控
南大通用GBase 8a MPP Cluster Linux端SQL进程监控工具
南大通用GBase 8a MPP Cluster Linux端SQL进程监控工具
|
24天前
|
运维 监控 Linux
Linux操作系统的守护进程与服务管理深度剖析####
本文作为一篇技术性文章,旨在深入探讨Linux操作系统中守护进程与服务管理的机制、工具及实践策略。不同于传统的摘要概述,本文将以“守护进程的生命周期”为核心线索,串联起Linux服务管理的各个方面,从守护进程的定义与特性出发,逐步深入到Systemd的工作原理、服务单元文件编写、服务状态管理以及故障排查技巧,为读者呈现一幅Linux服务管理的全景图。 ####
|
1月前
|
缓存 监控 Linux
linux进程管理万字详解!!!
本文档介绍了Linux系统中进程管理、系统负载监控、内存监控和磁盘监控的基本概念和常用命令。主要内容包括: 1. **进程管理**: - **进程介绍**:程序与进程的关系、进程的生命周期、查看进程号和父进程号的方法。 - **进程监控命令**:`ps`、`pstree`、`pidof`、`top`、`htop`、`lsof`等命令的使用方法和案例。 - **进程管理命令**:控制信号、`kill`、`pkill`、`killall`、前台和后台运行、`screen`、`nohup`等命令的使用方法和案例。
146 4
linux进程管理万字详解!!!
|
29天前
|
缓存 算法 Linux
Linux内核的心脏:深入理解进程调度器
本文探讨了Linux操作系统中至关重要的组成部分——进程调度器。通过分析其工作原理、调度算法以及在不同场景下的表现,揭示它是如何高效管理CPU资源,确保系统响应性和公平性的。本文旨在为读者提供一个清晰的视图,了解在多任务环境下,Linux是如何智能地分配处理器时间给各个进程的。
|
1月前
|
存储 运维 监控
深入Linux基础:文件系统与进程管理详解
深入Linux基础:文件系统与进程管理详解
86 8
|
1月前
|
网络协议 Linux 虚拟化
如何在 Linux 系统中查看进程的详细信息?
如何在 Linux 系统中查看进程的详细信息?
93 1
|
1月前
|
Linux
如何在 Linux 系统中查看进程占用的内存?
如何在 Linux 系统中查看进程占用的内存?
|
1月前
|
算法 Linux 定位技术
Linux内核中的进程调度算法解析####
【10月更文挑战第29天】 本文深入剖析了Linux操作系统的心脏——内核中至关重要的组成部分之一,即进程调度机制。不同于传统的摘要概述,我们将通过一段引人入胜的故事线来揭开进程调度算法的神秘面纱,展现其背后的精妙设计与复杂逻辑,让读者仿佛跟随一位虚拟的“进程侦探”,一步步探索Linux如何高效、公平地管理众多进程,确保系统资源的最优分配与利用。 ####
71 4