【Linux】进程信号 --- 信号预备阶段(入门篇)

news2024/9/22 3:35:37

在这里插入图片描述

👦个人主页:Weraphael
✍🏻作者简介:目前正在学习c++和算法
✈️专栏:Linux
🐋 希望大家多多支持,咱一起进步!😁
如果文章有啥瑕疵,希望大佬指点一二
如果文章对你有帮助的话
欢迎 评论💬 点赞👍🏻 收藏 📂 加关注😍


目录

  • 一、生活角度的信号
  • 二、进程信号的理解
  • 三、31个普通信号的作用
  • 四、进程收到信号现象
      • 4.1 前台进程和后台进程
      • 4.2 Ctrl + c热键
      • 4.3 硬件中断
  • 五、信号的概念

一、生活角度的信号

在我们日常生活中,信号是随处可见的,比如:

  • 红绿灯
  • 上下课铃声
  • 发令枪
  • ...

因为我们都接受过教育(识别信号)当产生这些信号时,会立马想到对应的处理动作,但不一定会立马去处理,因为现在可能正在做更重要的事,直到在合适的时候处理。比方说:闹钟一响就要起床学习【进程信号】,可是被窝太香了,起不来。所以,在信号产生后到信号处理这段期间内,必须记住(保存)信号

二、进程信号的理解

  1. 类似地,进程也必须能够识别和处理信号的能力。程序员们给操作系统内置了一批指令,一个指令表示一种特殊动作,而这些指令就是信号(进程信号)
  2. 当进程收到一个具体信号的时候,进程可能并不会立即处理这个信号,等到合适的时候处理。
  3. 一个进程从信号产生后到信号处理这段期间内,必须保存信号,等到合适的时候处理。

在这里插入图片描述

Linux中,可以通过以下命令查看当前系统中的信号列表

kill -l

在这里插入图片描述

以上是当前系统中的 进程信号,一共 62 个,其中 1~31 号信号为 普通信号(重点学习);剩下的 34~64 号信号为 实时信号(不考虑)

  • 普通信号:根据时间片实行公平调度,适用于个人电脑。(识别信号后可以不立即处理)
  • 实时信号:高响应,适合任务较少、需要快速处理的平台,比如汽车车机、火箭发射控制台。(识别信号后必须立即处理)

注意:Linux中,信号本质上就是一个数字,诸如:SIGKILLSIGINT等这些其实是

在这里插入图片描述

三、31个普通信号的作用

信号编号信号名信号含义
1SIGHUP如果终端接口检测到一个连接断开,默认处理动作是终止进程。
2SIGINT它的含义是Interrupt(中断)。这个信号通常由用户通过键盘(Ctrl + c)发送,默认是中断当前进程的运行。
3SIGQUIT当用户按组合键(一般采用Ctrl+\)时,该信号不仅终止前台进程组,同时会产生一个core文件。
4SIGILL此信号表示进程已执行一条非法指令,该信号的默认处理动作是终止进程,同时产生一个core文件。
5SIGTRAP该信号由断点指令或其他trap指令产生,该信号的默认处理动作是终止进程,同时会产生一个core文件。
6SIGABRT调用abort函数是产生此信号,进程异常终止,同时会产生一个core文件。
7SIGBUS当出现某些类型的内存故障时,常常产生该信号,该信号的默认处理动作是终止进程,同时产生一个core文件。
8SIGFPE此信号表示一个算术运算异常,比如除0、浮点溢出等,该信号的默认处理动作是终止进程,同时产生一个core文件。
9SIGKILL该信号不能被捕捉或忽略,它向系统管理员提供了一种可以杀死任一进程的可靠方法。
10SIGUSR1这是一个用户定义的信号,即程序员可以在程序中定义并使用该信号,该信号的默认处理动作是终止进程。
11SIGSEGV指示进程进行了一次无效的内存访问(比如访问了一个未初始化的指针),该信号的默认处理动作是终止进程并产生一个core文件。
12SIGUSR2这是另一个用户定义的信号,与SIGUSR1相似,该信号的默认处理动作是终止进程。
13SIGPIPE如果在管道的读进程已终止时对管道进行写入操作,则会收到此信号,该信号的默认处理动作是终止进程。
14SIGALRM当用alarm函数设置的定时器超时时产生此信号,或由setitimer函数设置的间隔时间已经超时时也产生会此信号。
15SIGTERM该信号是由应用程序捕获的,使用该信号让程序有机会在退出之前做好清理工作。与SIGKILL信号不同的是,该信号可以被捕捉或忽略,通常用来表示程序正常退出。
16SIGSTKFLT该信号指示协处理器上的堆栈故障(未使用),该信号的默认处理动作是终止进程。
17SIGCHLD在一个进程终止或停止时,SIGCHLD信号被发送给其父进程。按系统默认,将忽略此信号。如果父进程希望被告知其子进程的这种状态改变,则应捕捉此信号。信号捕捉函数中通常要调用一种wait函数以取得子进程id及其终止状态。
18SIGCONT可以通过发送该信号让一个停止的进程继续运行。
19SIGSTOP这时一个作业控制信号,该信号用于停止一个进程,类似于交互停止信号(SIGTSTP),但是该信号不能被捕捉或忽略。
20SIGTSTP交互停止信号,当用户按组合键(一般采用Ctrl+Z)时,终端驱动程序产生此信号并发送至前台进程组中的每一个进程。
21SIGTTIN后台进程读终端控制台时,由终端驱动程序产生此信号并发送给该后台进程,该信号的默认处理动作是暂停进程。
22SIGTTOU后台进程向终端控制台输出数据,由终端驱动程序产生此信号并发送给该后台进程,该信号的默认处理动作是暂停进程。
23SIGURG套接字上有紧急数据时,向当前正在运行的进程发出此信号,报告有紧急数据到达,该信号的默认处理动作是忽略。
24SIGXCPU进程执行时间超过了分配给该进程的CPU时间,系统产生该信号并发送给该进程,该信号的默认处理动作是终止进程,同时会产生一个core文件。
25SIGXFSZ如果进程写文件时超过了文件的最大长度设置,则会收到该信号,该信号的默认处理动作是终止进程,同时会产生一个core文件。
26SIGVTALRM虚拟时钟超时时产生该信号,与SIGALRM信号类似,但是该信号只计算该进程占用CPU的使用时间,该信号的默认处理动作是终止进程。
27SIGPROF该信号类似与SIGVTALRM,它不仅包括该进程占用CPU的时间还包括执行系统调用的时间,该信号的默认处理动作是终止进程。
28SIGWINCH当窗口大小发生变化时,内核会将该信号发送至前台进程组,该信号的默认处理动作是忽略。
29SIGIO此信号指示一个异步I/O事件,该信号的默认处理动作是终止进程。
30SIGPWR电源故障,该信号的默认处理动作是终止进程。
31SIGSYS该信号指示一个无效的系统调用,该信号的默认处理动作是终止进程,同时会产生一个core文件。

四、进程收到信号现象

4.1 前台进程和后台进程

  • 前台进程:进程默认情况下都是以前台方式运行,它会将输出结果直接发送到终端。通常,用户当前正在与之交互的进程称为前台进程。用户可以通过在终端按ctrl + c或者使用kill命令可以向进程发送信号9SIGKILL)终止前台运行的进程。
kill -9 <pid>
  • 后台进程:当进程以后台方式运行时,它不会占用终端并且不会阻塞用户的输入输出。用户可以通过以下命令将进程置于后台运行。但如果想杀掉进程只能用kill命令(命令如上)。
./myprocess &

注意:

  1. Linux中,一个终端会配上一个命令行解释器bash,并且一个终端只允许一个进程是前台进程,但可以允许多个进程为后台进程。
  2. 默认情况下,bash就是前台进程。当一个前台进程运行起来后,bash就变成了后台进程。
  3. 键盘输入首先被前台进程接收。
  4. Ctrl + c不会终止bash进程。因为bash进程对其做了特殊处理。

4.2 Ctrl + c热键

比方说我写了如下一个死循环代码

#include <iostream>
using namespace std;

int main()
{
    while (true)
    {
        cout << "我是一个进程,我在做死循环操作" << endl;
    }
    return 0;
}

当此程序运行起来后,不出意外就会在屏幕上疯狂打印。而以前在学习指令的时候说过,遇到这种类似的情况直接无脑Ctrl + c即可终止程序。

在这里插入图片描述

那么为什么就终止了呢?

当死循环程序运行起来后,就成为了前台进程,而bash则变成了后台进程。又因为键盘输入首先是被前台进程收到的,因此,Ctrl + c本质上是被前台进程解释成为了收到某种信号。

这里其实发出了一个 2号信号SIGINT

而进程信号的处理方式有三种:

  1. 系统默认动作
  2. 忽略处理(不处理)
  3. 用户自定义处理(信号捕捉)

首先可以确定的是 Ctrl + c收到信号的默认处理动作就是终止自己。那我能不能自定义处理信号动作呢?答案是当然可以的。

有一个系统调用接口signal用于自定义设置信号处理方式,其函数原型如下:

#include <signal.h>

typedef void (*sighandler_t)(int);

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

说明:

  • signum要处理的信号的编号。单纯地传递信号名也是可以的,因为信号名其实就是信号编号的宏定义。
  • handler是一个函数指针(函数地址)
void handler(int)
{
	// 自定义处理方式
}

显然,signal函数是一个回调函数,当某个信号被捕捉时,会去调用相应的函数,也就是执行相应的动作,此时signal函数的第一个参数会传递给handler函数做参数。

注意:

  1. signal函数可以设置在任何位置,一般建议在程序开始处设置。
  2. signal函数设置后,进程整个生命周期都有效。
  3. 触发signal函数不是本身,而是在执行后序代码的过程中触发的。(只有进程收到了信号signum,才会被调用。)
  4. 但并不是所有的信号都可以进行自定义处理。比如SIGKILLSIGSTOP等。
  5. 如果handler函数体内不写处理方式,那么信号的处理方式是系统默认的那一套。

比方说,我可以修改Ctrl + c信号的处理方式。自定义处理发生为:打印出自己收到了几号信号后,再退出进程。

#include <iostream>
#include <unistd.h>
#include <signal.h>
using namespace std;

void myhandler(int signum)
{
    cout << "信号编号为:" << signum << endl;
    exit(1);
}

int main()
{
    signal(SIGINT, myhandler);
    while (true)
    {
        cout << "我是一个进程,我在做死循环操作" << endl;
        sleep(1);
    }
    return 0;
}

【程序结果】

在这里插入图片描述

4.3 硬件中断

键盘数据(ctrl + c)是如何输入给操作系统的?当用户在键盘上输入完数据,操作系统是怎么知道键盘上有数据?

  • 在数据层面(指的是实际的数据存储和处理过程),CPU不从外设拿数据(不和外设打交道),而从内存中拿(因为内存访问速度比外设要快得多)。

  • 但在控制层面,CPU是可以读取外设的相关状态。这是通过与外部设备的控制器进行通信来实现的。外部设备控制器负责管理与外设的交互,包括数据的传输和状态的监测。

  • 当键盘有数据时,操作系统是通过硬件中断机制先知道的,这是因为计算机系统中的输入设备(如键盘)与CPU和操作系统之间的通信是通过中断来实现的。当外设有数据时,操作系统会采用中断的方式来通知CPU有重要事件发生(例如数据已经准备好等),其中包含硬件的中断号(是CPU用来识别不同中断类型的编号,存储在CPU的寄存器中)

  • CPU收到中断请求后,会暂停当前正在执行的任务,并根据中断号找到对应的中断向量表(本质上就是数组)中对应中断号的条目。中断向量表是一个存储在内存中的数据结构,由操作系统维护,表中的条目是调用硬件设备驱动程序的方法的地址,从而实现与硬件设备的交互。例如,处理硬盘中断的中断服务程序可能会调用硬盘驱动程序的函数来读取read或写入数据write

  • 中断处理程序调用对应硬件的方法将输入数据处理后存储到内存的输入缓冲区中。最后通过文件描述符传输给相应的上层应用程序。例如,终端程序通过文件描述符从操作系统读取用户输入的命令和操作。

在这里插入图片描述

所以,我们学习的进程信号其实就是模拟硬件中断实现的。后面的学习大家就能体会到。

ctrl + c又是如何变成信号的?

  • 在操作系统中,键盘输入可以包含普通字符(如字母等)和特殊控制字符(ctrl + c等)。对于前者是可以回显的,而后者不回显。
  • 因此操作系统首先会判断用户输入的是什么类型的字符,对于普通字符就直接从键盘文件拷贝到内核缓冲区;如果是特殊控制字符,操作系统会将解释成为某个信号发送给前台进程。

五、信号的概念

信号的产生和我们自己的代码的运行是 异步。属于软中断(软件中断)

  • 异步:程序不必按照严格的顺序依次执行。比方说:老师上课叫一名同学去办公室拿“小蜜蜂”,老师不等他回来而是继续上课。
  • 同步:程序按照预定顺序依次执行,每一步必须等待上一步完成后才能执行。就比方说:老师上课叫一名同学去办公室拿“小蜜蜂”,等他/她回来了才开始上课。
  • 换言之,信号什么时候产生我们并不清楚,但是我们只需继续运行我们的代码,等着未来某个时刻信号的到来。

注意:信号一定是由操作系统(管理者)发送给进程的 ~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1930428.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PIC单片机ICSP接口电路原理图

ICSP接口电路只有五根线&#xff0c;依次为&#xff1a; VPP、VDD、VSS、PGD、PGC&#xff0c;它们与PIC单片机的连接如下图&#xff1a; 题外话单片机中的佼佼者是谁&#xff0c;想知道点击上方图片查看视频 为保证ICSP安全正常工作&#xff0c;烧写时序线PGD和PGC、烧写电压…

C语言 | Leetcode C语言题解之第237题删除链表中的节点

题目&#xff1a; 题解&#xff1a; /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/void deleteNode(struct ListNode* node) {struct ListNode * p node->next;int temp;temp node->val;node->val…

深度学习驱动智能超材料设计与应用

在深度学习与超材料融合的背景下&#xff0c;不仅提高了设计的效率和质量&#xff0c;还为实现定制化和精准化的治疗提供了可能&#xff0c;展现了在材料科学领域的巨大潜力。深度学习可以帮助实现超材料结构参数的优化、电磁响应的预测、拓扑结构的自动设计、相位的预测及结构…

线程控制

对线程的控制思路和进程相似&#xff0c;创建、等待、终止&#xff0c;只需要调用接口就行。但是在Linux下没有线程的概念&#xff0c;因为Linux的设计者认为&#xff0c;线程是一种轻量级的进程&#xff0c;毕竟创建线程只需要创建PCB。因此Linux中使用多线程必须使用第三方pt…

打破平台限制,使智能手机和平板电脑上无缝运行Windows x86/x64架构的软件和游戏的一款安卓应用

大家好&#xff0c;今天给大家分享一款专为Android设备设计的模拟器应用Winlator。其核心功能是能够在基于ARM架构的智能手机和平板电脑上无缝运行Windows x86/x64架构的软件和游戏。 Winlator是一款Android应用程序&#xff0c;它允许用户使用Wine和Box86/Box64在Android设备上…

Ubuntu的磁盘扩容遇到的问题

1.先用终端上的命令查看磁盘的使用情况 #查看磁盘空间容量的占用情况 $ df -h #查看当前文件夹中&#xff0c;各个文件占用磁盘空间的情况 $ du -sh* 如果容量少的话&#xff0c;需要尽快扩容 2.开机前的扩容 2.1 VMware 扩展磁盘空间 关闭当前客户机&#xff0c;在编辑虚拟…

《企业实战分享 · Druid 连接监控》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; 近期刚转战 CSDN&#xff0c;会严格把控文章质量&#xff0c;绝不滥竽充数&#xff0c;如需交流&#xff…

华为以客户为中心的战略

2005年&#xff0c;伴随着国际化步伐的加快&#xff0c;华为重新梳理了自己的愿景、使命和发展战略&#xff0c;提出了以客户为中心的战略定位&#xff1a; 为客户服务是华为存在的唯一理由&#xff1b;客户需求是华为发展的原动力。质量好、服务好、运作成本低&#xff0c;优…

部署kafkamanager

1&#xff0c;检查kafka的版本 到lib下查看 libs/kafka-clients-0.11.0.3.jar kafka的版本 0.11 2&#xff0c;下载kafkamanager 链接&#xff1a; https://pan.baidu.com/s/1qYifoa4 密码&#xff1a;el4o 3&#xff0c;解压后更改该conf下conf/application.conf 中zkhosts …

VUE:跨域配置代理服务器

//在vite.config。js中&#xff0c;同插件配置同级进行配置server:{proxy:{"/myrequest":{//代理域名&#xff0c;可自行修改target:"https://m.wzj.com/",//访问服务器的目标域名changeOrigin:true,//允许跨域configure:(proxy,options) > {proxy.on(&…

Ubuntu上安装配置samba服务

Ubuntu上安装配置samba服务 在Ubuntu中安装配置samba共享服务&#xff0c;可以让你在网络上共享文件和打印机。以下是一个相对详细的步骤指南&#xff0c;介绍如何在Ubuntu上安装和配置Samba。 1. 安装Samba 首先&#xff0c;需要安装Samba软件包。打开终端并运行以下命令&a…

【学习笔记】无人机系统(UAS)的连接、识别和跟踪(一)-3GPP TS 23.256 技术规范概述

3GPP TS 23.256 技术规范&#xff0c;主要定义了3GPP系统对无人机&#xff08;UAV&#xff09;的连接性、身份识别、跟踪及A2X&#xff08;Aircraft-to-Everything&#xff09;服务的支持。 3GPP TS 23.256 技术规范&#xff1a; 以下是文档的核心内容总结&#xff1a; UAV系…

设计模式-概述*

1.代码的质量的评判 可维护性&#xff1a;不破坏原有代码设计以及不引入新的bug的前提下&#xff0c;能够快速修改或新增代码&#xff1b;可读性&#xff1a;人类能理解的代码&#xff08;编程规范-命名、函数是否冗长、类是否过大等&#xff09;&#xff1b;可扩展性&#xff…

BiliBili 阴阳师主题 前端技术展示

实现效果 实现方式 纯 Html CSS 文件展示如下 下载地址 https://download.csdn.net/download/qq_43638033/89543490 部分代码解析 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"> <!-- 设置文档的字符编码…

【概率论三】参数估计

文章目录 一. 点估计1. 矩估计法2. 极大似然法1. 似然函数2. 极大似然估计 3. 评价估计量的标准2.1. 无偏性2.2. 有效性2.3. 一致性 三. 区间估计1. 区间估计的概念2. 正态总体参数的区间估计 参数估计讲什么 由样本来确定未知参数参数估计分为点估计与区间估计 一. 点估计 所…

每日刷题(cf)

目录 1.C. Increasing Sequence with Fixed OR 2.C. Jellyfish and Green Apple 3.B. Jellyfish and Game 1.C. Increasing Sequence with Fixed OR Problem - C - Codeforces 题目要求我们构造一个最长的序列&#xff0c;使得任意相邻两个元素按位或等于n&#xff0c;我们对…

汇智知了堂推出“鸿蒙系统开发培训”,探索万物互联新纪元

在数字化转型的浪潮中&#xff0c;操作系统作为连接硬件与软件的桥梁&#xff0c;其重要性不言而喻。随着5G、物联网、人工智能(AI)等技术的飞速发展&#xff0c;我们正步入一个万物皆可互联的时代。在这个背景下&#xff0c;华为推出的鸿蒙系统(HarmonyOS)应运而生&#xff0c…

【C语言习题】41.序列中删除指定数字

文章目录 题目代码 题目 代码 #include<stdio.h> int main() {int i,j;int n;int arr_1[100];int arr_2[100];int del;scanf("%d",&n);for(i0;i<n;i){scanf("%d",&arr_1[i]);}scanf("%d",&del);for(i0,j0;i<n;i){if(de…

【Linux】进程信号 --- 信号产生

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和算法 ✈️专栏&#xff1a;Linux &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵&#xff0c;希望大佬指点一二 如果文章对…

【安全】系统安全设计规范(DOC完整版)

1.1安全建设原则 1.2 安全管理体系 1.3 安全管理规范 1.4 数据安全保障措施 1.4.1 数据库安全保障 1.4.2 操作系统安全保障 1.4.3 病毒防治 1.5安全保障措施 1.5.1实名认证保障 1.5.2 接口安全保障 1.5.3 加密传输保障 1.5.4终端安全保障 软件资料清单列表部分文档&…