【Linux课程学习】:第20弹---信号入门专题(基础部分)

ops/2024/12/15 15:03:40/

🎁个人主页:我们的五年

🔍系列专栏:Linux课程学习 

🌷追光的人,终会万丈光芒

🎉欢迎大家点赞👍评论📝收藏⭐文章

Linux学习笔记:

 https://blog.csdn.net/djdjiejsn/category_12669243.html

前言:

信号这专题也是很重要的,对之前学过的知识再次关联起来,形成闭环,对理解Linux操作系统有很大的帮助。信号的学习包含:1.信号的产生,2.信号的保存,3.信号的处理这三方面。关于信号的保存,在没学信号之前可能不太理解,学了以后,这步是必不可少的,因为在收到信号以后,因为block,可能不会马上处理。下面我们进行详细的讲解。

目录

一.信号入门-生活角度的信号:

 二.技术角度的信号:

2.1键盘Ctrl+c产生信号:

三.前台进程和后台进程

3.1前台进程:

3.2后台进程:

3.3关于前台进程和后台进程的命令:

四.信号的分类

4.1kill -l查看所有的信号:

4.2信号的终止:

 五.信号处理的常见方式

5.1信号处理的方式有三种:

5.2对信号进行自定义处理:

5.3对signal的应用


一.信号入门-生活角度的信号:

对于日常生活来说,平常的闹钟,语言,铃声……这些都是信号,对于如何从生活中的信号去和Linux操作系统中的信号进行联系,我引入了下面这一个例子:

在我们点好外卖以后,外卖小哥会接单,商家会处理。但是我们点好外卖以后就可以去等外卖送到门口了,我们不需要关心怎么送到的,其他等问题,我们就和外卖小哥形成了异步。等外卖到了以后,会有电话或者门铃等信号告知我们外卖来了。但是我们不会马上处理这个信号,也就是说,但是我们心中是知道有这一个信号来了的。多久处理就是看其他各种情况了。在过了一会以后,我们处理这个信号,我们可以把外卖拿进去吃,也可以拿进去不吃,也可以干脆不去拿,忽略这一个信号了(啥都不干)。所以这就是处理信号。然后处理信号之前就是信号的保存等问题了。


 二.技术角度的信号:

2.1键盘Ctrl+c产生信号:

在我们启动一个shell进程,然后运行一个死循环的程序。如果我们想要这个进程(前台进程)退出,我们就可以在键盘下按下Ctrl+c(Ctrl+c其实就是2号信号,SIGINT),就可以杀死进程了。它的逻辑先是这样的:

1.键盘按Ctrl+c组合键,键盘产生一个中断。 

2.这个终端被操作系统获取,其实CPU的针脚能察觉到,然后OS操作系统可以拿到这个信息。

3.OS就可以去给一个进程发信号。

发信号的本质:去改进程PCB中的pending位图。

Ctrl+c:不能终止后台进程。


三.前台进程和后台进程

前台进程进程在终端用户界面中运行
后台进程不占用用户的终端

3.1前台进程:

🍟前台进程的定义:

前台进程是用户启动并且需要保持与用户交互的进程。这些进程在终端用户界面中运行,用户可以直接控制和管理它们

🍟产生方式:

一般./test运行的就是前段进程。

🍟特点:

1.占用终端:前台进程会一直占用终端,直到它运行结束或者被暂停(如通过Ctrl+Z组合键)。在它运行期间,终端不能用于其他操作,除非暂停或终止这个前台进程

2.对终端信号敏感:前台进程会接收并处理终端发送的信号。例如,当用户在终端中按下Ctrl+C组合键时,前台进程会收到SIGINT(中断信号)并通常会终止运行,除非它对这个信号进行了特殊的处理(如信号捕获和忽略)。

3.状态显示:当前台进程正常运行时,在ps命令的输出中(如ps -ef)显示为R状态,表示正在运行并占用CPU资源。如果通过Ctrl+Z组合键暂停了前台进程,它的状态会变为T,表示停止运行

3.2后台进程:

🍟后台进程的定义:

后台进程是在后台运行的进程,它们不占用用户的终端,用户也不需要直接与之交互。后台进程通常用于执行一些不需要用户立即关注的任务,比如长时间的计算任务、数据备份任务、服务器的守护进程等。

🍟产生方式:

在前台进程后面加上&符号就是后台进程。

🍟特点:

1.不占用终端I/O:后台进程不会阻止用户在终端进行其他操作,它的输出信息(标准输出和标准错误输出)可以通过重定向的方式保存到文件中,这样就不会在终端显示,干扰用户的其他操作。例如,可以使用“>output.log 2>error.log”来分别将标准输出和标准错误输出重定向到output.log和error.log文件中。
2.对信号处理方式不同:后台进程也会接收信号,但对一些信号的默认处理方式可能和前台进程不同。例如,后台进程一般不会因为Ctrl+C而终止,除非它专门对SIGINT信号进行了处理。
3.状态显示:后台进程在正常运行时也显示为R状态,不过它不会占用终端的I/O设备。和前台进程类似,后台进程也可以被暂停,状态变为T。可以使用bg命令让它在后台继续运行,或者用fg命令将其恢复到前台运行。

3.3关于前台进程和后台进程的命令:

fg //把后台进程放到前台。
bg //让暂停的后台进程继续运行。
jobs //查看前后台进程的信息


四.信号的分类

4.1kill -l查看所有的信号:

如果要查看更详细的信号信息,可以在man 7 signal中查看

下面就表示信号的分类,其实这些都是定义的宏,用数字也是一样的。

对于34号以后的信号是实时信号,我们这里不理解。主要研究的是34号以下的,1到31号。这里有31个信号,用一个int位图就能表示出来。

刚刚我们使用的信号:
1.Ctrl+c:SIGINT(2号信号)

2.Ctrl+\:SIGQUIT(3号信号)

4.2信号的终止:

信号终止一般有core和term终止。在man 7 signal中就会有详细的介绍,里面就会有是core终止还是term终止进程。

core和term终止进程基本差不多,唯一不同的就是:
如果进程发生core终止,可能会生成core文件。

但是必须是我们先把core file的大小调成大于0,这样才能生成core文件!!!

ulimit -c 1024:把core file文件改成1024字节。

ulimit -a:查看相关信息。


 五.信号处理的常见方式

5.1信号处理的方式有三种:

1.忽略此信号。

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

3.提供一个信息处理函数,要求内核在处理这个信号的时候,切换到用户态执行这个函数,这种方式成为捕捉

5.2对信号进行自定义处理:

对信号进行自定义处理的函数是:

头文件:

#include <signal.h>

函数原型:

typedef void (*sighandler_t)(int);
 sighandler_t signal(int signum, sighandler_t handler);

函数解释:

1.signum表示的是要对几号信号进行处理。

2.handler是一个函数指针,表示的是自定义的方式。

typedef void (*sighandler_t)(int);

它的类型是一个返回值为void,参数为int的函数指针。

也可以传这些参数:
SIG_IGN:表示的是处理信号的方式是忽略此信号

SIG_DFL:执行该信号的默认行为

5.3对signal的应用

对signal的应用,我们可以通过命令行参数,就可以在shell命令行中对指定的信号进行指定的修改。

我们还可以通过for循环对31个信号的执行方式进行修改。那么以后OS给我们写的程序的进程发的终止信号就不起作用了。

那是不是我们的进程就一直不会被杀掉呢?

答案:9号信号是不运行我们进行修改的,它的行为会一直是终止进程。所以我们的进程是肯定能被杀死的。

下面是关于signal的应用:

#include <iostream>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>void Handler(int signo)
{std::cout << "l love xy!signo:" << signo << std::endl;
}void Uuage(std::string s)
{std::cout << "please use:" << std::endl;std::cout << s << " signo" << " pid" << std::endl;
}int cout = 0;
void die(int signo)
{std::cout << " cout:" << cout << std::endl;abort();
}int main(int argc, char *argv[])
{// 服务器,一秒可以累加多少次alarm(100);signal(SIGINT, die);sleep(5);unsigned int n = alarm(5);std::cout << n << std::endl;// abort();// std::cerr << "kill" << std::endl;// // raise(9);// if (argc != 3)// {//     Uuage(argv[0]);//     exit(1);// }// //-signum   信号的类型// int signum = std::stoi(argv[1] + 1);// // std::cout << signum << std::endl;// // pid// pid_t id = std::stoi(argv[2]);// int n = ::kill(id, signum);// if (n < 0)// {//     std::cerr << "kill" << std::endl;// }// 如果一直没有调用,那么Handler就一直不会被调用!// 不要放在循环中,因为只要进行说明一次,就会进行保存!// 九号信号是不能被捕捉的!!!// 不然如果把终止进程的信号全部捕捉,一个进程就不能被杀死// for (int i = 1; i <= 31; i++)// {//     signal(i, Handler);// }// while (1)// {//     std::cout << "pid:" << getpid() << std::endl;//     sleep(1);// }// int num = 0;// while (1)// {//     std::cout << "num:" << num << std::endl;//     sleep(1);//     ++num;// }return 0;
}

到这里文章就基本结束了,作为C++程序员,请保持持续的学习,每天的算法练习!在这里欢迎大家和我一起交流问题,共同进步。 

🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷


http://www.ppmy.cn/ops/142137.html

相关文章

外卖开发(九)——Excel数据报表ApachePOI

外卖开发&#xff08;九&#xff09;——Excel数据报表 一、ApachePOI二、入门案例三、导出运营数据报表1、ReportController2、ReportService 一、ApachePOI Apache POl是一个处理Miscrosoft Office各种文件格式的开源项目。简单来说就是&#xff0c;我们可以使用POI在Java程…

LINUX——shell编程

Shell 简介 Shell 是一个 C 语言编写的脚本语言&#xff0c;它是用户与 Linux 的桥梁&#xff0c;用户输入命令交给 Shell 处理&#xff0c; Shell 将相应的操作传递给内核&#xff08;Kernel&#xff09;&#xff0c;内核把处理的结果输出给用户。 下面是流程示意图&#xff…

【4】数据分析基础(pandas中的series 1)

学习目标2 pandas模块的学习。 pandas是一个基于NumPy的模块&#xff0c;它的功能在于数据的筛选清洗和处理&#xff0c;与NumPy模块相比&#xff0c;pandas模块更擅长处理二维数据。 pandas模块主要有Series和DataFrame两种数据结构。 接下来&#xff0c;我们先学习Series…

Kubernetes 的 Web UI 仪表板部署以及使用

前言 Kubernetes 仪表盘为集群提供了基于网页的用户界面。人们可以使用该仪表盘在集群上部署应用程序&#xff0c;也可以对集群中已有的应用程序进行故障排查。此外&#xff0c;该仪表盘还能让人深入了解集群中的资源情况。它由 Kubernetes 官方提供&#xff0c;人们能够通过它…

使用DuckDB 加载和清洗数据

DuckDB CLI是允许用户直接从命令行与DuckDB交互的工具。前文你看到了如何使用Python与DuckDB交互。但是&#xff0c;有时你只是想直接使用数据库—例如在创建新表、从不同数据源导入数据以及执行与数据库相关的任务时。在这种情况下&#xff0c;直接使用DuckDB CLI要有效得多。…

AI来了,云原生更稳了

不了解AI的时候&#xff0c;往往会将其视为洪水猛兽&#xff0c;因为AI确实具有颠覆一切的巨大能量&#xff1b;但是当你慢慢接近它、拥抱它甚至尝试驾驭它&#xff0c;你会发现AI如同其他许多新技术一样&#xff0c;都需要扎根的土壤、生长的养分和成熟过程中适宜的环境等。 “…

【0x000A】HCI_Reject_Connection_Request命令详解

目录 一、命令概述 二、命令格式及参数说明 2.1. HCI_Reject_Connection_Request命令格式 2.2. 参数说明 2.2.1. BD_ADDR&#xff08;蓝牙设备地址&#xff09; 2.2.2. Reason&#xff08;拒绝原因&#xff09; 三、返回事件及参数说明 3.1. 返回参数 3.2. 生成的事件…

Django结合websocket实现分组的多人聊天

其他地方和上一篇大致相同&#xff0c;上一篇地址点击进入, 改动点1&#xff1a;在setting.py中最后再添加如下配置&#xff1a; # 多人聊天 CHANNEL_LAYERS {"default":{"BACKEND": "channels.layers.InMemoryChannelLayer"} }因此完整的se…