Liunx进程信号

进程信号

  • 进程信号
    • 什么是信号
    • liunx信号种类
  • 前后台进程
    • 前后台进程的概念
  • 进程信号的产生
    • 键盘产生
  • 阻塞信号
    • 信号的捕捉
      • 用户态和内核态
    • 信号的捕捉函数

进程信号

什么是信号

信号是Unix、类Unix以及其他POSIX兼容的操作系统中进程间通讯的一种有限制的方式。它是一种异步的通知机制,用来提醒进程一个事件已经发生。当一个信号发送给一个进程,操作系统中断了进程正常的控制流程,此时,任何非原子操作都将被中断。如果进程定义了信号的处理函数,那么它将被执行,否则就执行默认的处理函数。

liunx信号种类

Liunx中如何查看信号种类:
在这里插入图片描述

信号名称信号编号描述
SIGHUP1终端挂起或控制进程结束
SIGINT2终止进程(由键盘输入 Ctrl+C 产生)
SIGQUIT3终止进程并生成核心转储文件(由键盘输入 Ctrl+\ 产生)
SIGILL4非法指令
SIGTRAP5跟踪陷阱
SIGABRT6终止进程并生成核心转储文件(由调用 abort() 函数产生)
SIGBUS7非法地址访问
SIGFPE8浮点异常
SIGKILL9无条件终止进程
SIGUSR110用户定义的信号1
SIGSEGV11无效的内存引用
SIGUSR212用户定义的信号2
SIGPIPE13管道破裂
SIGALRM14定时器超时
SIGTERM15请求终止进程(默认终止信号)
SIGSTKFLT16协处理器栈错误
SIGCHLD17子进程状态改变
SIGCONT18继续被暂停的进程
SIGSTOP19停止进程
SIGTSTP20暂停进程(由键盘输入 Ctrl+Z 产生)
SIGTTIN21后台进程尝试读取控制终端
SIGTTOU22后台进程尝试写控制终端
SIGURG23套接字的紧急情况
SIGXCPU24CPU 时间限制超时
SIGXFSZ25文件大小限制超过
SIGVTALRM26虚拟定时器超时
SIGPROF27分析计时器超时
SIGWINCH28窗口大小调整
SIGIO29异步 I/O 事件
SIGPWR30电源故障
SIGSYS31非法系统调用

前后台进程

前后台进程的概念

前台进程在命令行操作时,只能有一个,后台进程可以有多个。

接下来我们启动一个后台进程。
我们创建一个后台进程,并且让他给文件不停的写入。
在这里插入图片描述
此时我们查看 log.txt
在这里插入图片描述
可以看到。进程在后台运行,那我们如何查看呢?
jobs 就可以看到
在这里插入图片描述
如何杀掉后台进程呢? 我们需要把fg后台放到前台,然后退出。
在这里插入图片描述
下面附上常用命令:

快捷键描述
Ctrl+C终止并退出前台进程,回到Shell
Ctrl+Z暂停前台命令执行,放到后台,回到Shell
jobs查看当前在后台执行的命令
&在后台执行命令
fg N将进程号码为N的命令放到前台执行
bg N将进程号码为N的命令放到后台执行

进程信号的产生

键盘产生

用户在Linux下执行一个前台进程,然后使用ctrl+c操作,会直接终止掉该前台进程。这是因为用户按下ctrl+c,这个键盘输入产生一个硬件中断,被OS获取,解释成信号,发送给目标前台进程,前台进程因为收到信号,进而引起进程退出。

ctrl+c组合键只能终止掉前台进程,对后台进程无效。这时我们可以使用kill -9指令来该终止进程
在这里插入图片描述
crtl+c的信号本质就是2号信合
在这里插入图片描述
接下来我们通过一个函数验证这个事:
在这里插入图片描述
在这里插入图片描述
像进程发送2号信合,运行新程序。
查看进程退出码:echo $?
在这里插入图片描述

························································································································································

阻塞信号

信号的常见分类:

  1. 实际执行信号的处理动作,称为信号递达(Delivery)。
  2. 信号从产生到递达之间的状态,称为信号未决(pending)。
  3. 进程可以选择阻塞(Block)某个信号。
    被阻塞的信号产生时将保持在未决状态,直到进程解除对此信号的阻塞,才执行递达的动作。

需要注意的是,阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后的一种处理动作。

在内核中的表示
未决信号,就是你的进程已经接收到了信号了,只是还没被信号处理函数处理的那些信号。

特别说明:虽然未决信号的定义是上面这样,但是这里我们需要更加具体一点,未决信号特指进程收到且被阻塞的信号。

在这里插入图片描述

  1. 每个信号都有两个标志位分别表示阻塞(block)和未决(pending),还有一个函数指针表示处理动作。信号产生时,内核在进程控制块中设置该信号的未决标志,直到信号递达才清除该标志。
  2. 在上图中,SIGHUP信号未阻塞也未产生过,当它递达时执行默认处理动作。
  3. 在上图中,SIGINT信号产生过,但正在被阻塞,所以暂时不能递达。虽然它的处理动作是忽略,但在没有解除阻塞之前不能忽略这个信号,因为进程仍有机会在改变处理动作之后再接触阻塞。
  4. 在上图中,SIGQUIT信号未产生,正在被阻塞,不能执行自定义函数。
  5. 处理动作包括默认、忽略以及自定义。
    sigset_t
    根据信号在内核中的表示方法,每个信号的未决标志只有一个比特位,非0即1,如果不记录该信号产生了多少次,那么阻塞标志也只有一个比特位。

sigset_t称为信号集,这个类型可以表示每个信号的“有效”或“无效”状态。

在阻塞信号集中“有效”和“无效”的含义是该信号是否被阻塞。 在未决信号集中“有效”和“无效”的含义是该信号是否处于未决状态。
阻塞信号集也叫做当前进程的信号屏蔽字(Signal Mask)

信号集操作函数
sigset_t类型对于每种信号用一个bit表示“有效”或“无效”,至于这个类型内部如何存储这些bit则依赖于系统的实现,从使用者的角度是不必关心的,使用者只能调用以下函数来操作sigset_t变量,而不应该对它的内部数据做任何解释,比如用printf直接打印sigset_t变量是没有意义的。

#include <signal.h>

int sigemptyset(sigset_t *set);// 对指定信号集进行清空。

int sigfillset(sigset_t *set);//对指定信号集进行置1

int sigaddset(sigset_t *set, int signum);//将指定的信号signum添加到信号集中 也就是置1

int sigdelset(sigset_t *set, int signum);//将指定的
信号signum在信号集中置0
int sigismember(const sigset_t *set, int signum); //判定signum是否为1 

接下来介绍重要函数:

#include<signal.h>
 int sigprocmask(int how,const sigset_t *set,__sigset_t *oset);
 //若返回成功则返回0.

how参数

选项含义
SIG_BLOCK设置包含了我们希望添加到当前信号屏蔽字的信号,相当于 `mask = mask
SIG_UNBLOCK设置包含了我们希望从当前信号屏蔽字中解除阻塞的信号,相当于 mask = mask & ~set
SIG_SETMASK设置当前信号屏蔽字为 set 所指向的值,相当于 mask = set

接下来我们屏蔽2号信合!
在这里插入图片描述

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

void handler(int signo)
{
    cout<<"handler get signo:"<<signo<<endl;
}

int main()
{
   signal(2,handler);
   //set==block oset== oblock
    sigset_t set,oset;

    sigemptyset(&set);//初始化
    sigemptyset(&oset);

sigaddset(&set,2);//设置对2号信合屏蔽 但是并没有设置进入系统

    sigprocmask(SIG_BLOCK,&set,&oset);
    while(1)
    {
        cout<<"mypid:"<<getpid()<<endl;
        sleep(1);
    }
    return 0;
}

#############################

设置完成后,我们对代码进行编译。

在这里插入图片描述

可以发现我对2号信合免疫了。

pending未决队列表的获取:

sigpending

读取当前进程的未决信号集,通过set参数传出来。


接下来我们以一个综合案例操作:

  1. 屏蔽2号信合 这个屏蔽是阻塞
  2. 通过sigpending查询2号信合
  3. 发送2号信合。
    在这里插入图片描述
    我们可以看到,发送2号信合,此时2号信合处于未决状态。
    在10次后,我们取消对2号的阻塞
    在这里插入图片描述

信号的捕捉

信号的捕捉发生在用户态和内核态的互相转换中,首选我们必须先知道什么是用户态,什么是内核态。

用户态和内核态

在这里插入图片描述

①OS在不在内存中被加载呢? ?——在 无论进程怎么切换,我们都可以找到内核的代码和数据,前提是你只要能够有权利访问!

②当前进程如何具备权利 访问这个内核页表乃至访问内核数据呢?——要进行身份切换。
进程如果是用户态的——>只能访问用户级页表 0~3G
进程如果是内核态的——>访问内核级和用户级的页表 3~4G 、③我怎么知道我是用户态的还是内核态的呢?
CPU内部有对应的状态寄存器CR3, CR3有比特位标识当前进程的状态 0:内核态,3:用户态

④0—>3
用户态切到内核态的情况:1.系统调用的时候。2.时间片到了,进程间切换。3.其他等等。执行完毕就继续切回用户态。即:程序运行从用户态切换到内核态的操作:中断/异常/系统调用,例如

    <1> 整数除以零操作会导致用户态—>内核态:因为会导致程序异常(分母不能为0)

    <2> sin()函数调用操作不会切换状态,因为库函数并不会引起运行态的切换

    <3> read 系统调用操作会导致用户态—>内核态:符合系统调用接口

⑤内核态vs用户态 内核态可以访问所有的代码和数据——内核态具备更高权限 用户态只能访问自己的

⑥我们的程序,会无数次直接或者间接的访问系统级软硬件资源(管理者是OS),本质上,你并没有自己去操作这些软硬件资源,而是必须通过OS-

无数次的陷入内核(1.切换身份3->0 2.切换页表,切到内核级页表)->调用内核的代码->完成访问的动作->结果返回给用户(1.切换身份0->3 2. 切换页表,切到用户级页表)->用户得到结果

⑦while(1);死循环进程普通程序会身份切换吗? —>也会陷入内核,来回切换身份 —>你也有自己的时间片
—>时间片到了的时候->OS收到中断信息,把进程从cpu移走,进程切到内核态,更换内核级页表 —>保护上下文,执行调度算法
—>选择了新的进程 —>恢复新进程的上下文 —>用户态,更换成用户级页表 —>CPU执行的就是新进程的代码!

重点: 用户态到内核态的两种切换场景:

  1. 除0错误。操作系统互捕捉这个错误,并且切换到内核态
  2. 使用系统调用函数接口,会从用户态切换到内核态。

自定义捕捉信号的处理过程
在这里插入图片描述
这个图是对自定义信号的处理,以及检测时机。

  1. 调用系统调用函数,此时用户态切换内核态
  2. 此时操作系统处理完之后,检测处理信号
  3. 信号为自定义信号处理方式 ,内核态不处理用户态代码
  4. 处理完成,继续返回内核态
  5. 从内核态返回用户态

在这里插入图片描述
正无穷记忆法!!!

信号的捕捉函数

  1. signal 常用捕捉函数
  2. sigaction 信号捕捉函数
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); 

该函数需要将方法写入结构体中。

struct sigaction {  
    void     (*sa_handler)(int);  
    void     (*sa_sigaction)(int, siginfo_t *, void *);  
    sigset_t   sa_mask;  
    int        sa_flags;  
    void     (*sa_restorer)(void);  
};

**sa_handler:**这是一个指向函数的指针,当接收到指定的信号时,这个函数会被调用。如果设置为 SIG_IGN,则忽略该信号;如果设置为 SIG_DFL,则使用默认的信号处理行为。
**sa_mask:**这是一个信号集,用于在信号处理函数执行期间阻塞的信号。这确保了在处理一个信号时,不会受到其他信号的干扰。 也就是说,阻塞二号信号的
其他的几个参数并不需要我们了解。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机专业,不擅长打代码,考研该怎么选择?

考研其实和你的代码能力关系不大 所以在选学校以前可以看看有哪些学校复试是要求上机撸代码的&#xff0c;可能会要求比较严 初试真的不用担心代码问题&#xff0c;我也是基本零编程能力就开始备考考研的... 本人双非科班出身备考408成功上岸&#xff0c;在这里也想给想考40…

先登杯·14天创作挑战营·第④期~ 等你来战!

文章目录 ⭐️ 活动介绍⭐️ 活动详情⭐️ 活动奖品⭐️ 活动流程​⭐️ 评审规则⭐️ 报名&投稿注意事项⭐️ 活动组织 ​ 活动报名入口&#xff1a;https://bbs.csdn.net/topics/618374514 本次活动与官方活动及其他博主的创作型活动并不冲突&#xff01; ​ ​ ⭐️…

练习 22 Web [极客大挑战 2019]BuyFlag

php弱类型比较&#xff0c;注意Cookie值&#xff0c;php利用数组赋值进行绕过,科学计数法 很明显是弱类型比较&#xff0c;之前的练习题已经遇到过 构造password404adsffd&#xff0c;后面随便什么字母都行 然后 money100000000 然后在student这里卡了很久&#xff0c;post…

python解决既约分数(gcd)

题目&#xff1a; 如果一个分数的分子和分母的最大公约数是1&#xff0c;这个分数成为既约分数。例如3/4、1/8、7/1、都是既约分数。请问&#xff0c;有多少个既约分数&#xff0c;分子和分母都是1到2020之间的整数&#xff08;包括1和2020&#xff09;&#xff1f; 分析&#…

Leetcode 17.电话号码的字母组合

题目 思路 输入的digits有几个数就有几层。 一层中有几个数则取决于输入的数字对应的字母有几个。 1.确定递归函数的返回值及参数&#xff1a; 其实参数不是一开始就确定好的&#xff0c;而是你在写递归函数的时候缺啥&#xff0c;就往进去传啥。 这里我就直接全部写出来。…

基于单片机的智能报站系统仿真设计

**单片机设计介绍&#xff0c;基于单片机的智能报站系统仿真设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的智能报站系统仿真设计概要是关于采用单片机技术实现公交车报站功能的系统设计概述。以下是对该设计的…

基于Android studio的二手交易平台--原创

&#x1f345;文章末尾有获取完整项目源码方式&#x1f345; 目录 一、实现介绍 视频演示 1.1 启动页实现 1.2登录页 1.3注册页 1.4忘记密码 1.5首页 1.6发布页 1.7我的发布 1.8我的收藏 1.9详情页 1.10修改页面 1.11我的页面 ​编辑 二、获取源码 一、实现介…

MATLAB——知识点备忘

最近在攻略ADC建模相关方面&#xff0c;由好多零碎的知识点&#xff0c;这里写个备忘录。 Matlab 判断一个数是否为整数 1. isinteger 函数 MATLAB中&#xff0c;可以使用 isinteger 函数来判断一个数是否为整数&#xff0c;例如&#xff1a;要判断x是否为整数可以采用以下代…

DXP实验3-单片机时钟显示系统的层次原理图设计

目录 一&#xff0c;自上而下的子母图设计 1&#xff0c;绘制层次式电路母图 1)工程及原理图创建和保存 2)开始绘制层次式母图main.SchDoc 2&#xff0c;绘制图纸符号 1&#xff09;properties选项卡 2&#xff09;designator标号 3&#xff09;filename文件名 4&…

[WinForm开源]原神混池模拟器-蒙德篇:软件的基本介绍、使用方法、常见问题解决与代码开源

首先先和各位旅行者道个歉&#xff0c;混池都过去这么久了才把软件开发好并发布出来 >_< 创作目的&#xff1a;为给各位旅行者&#xff08;当然包括我自己&#xff09;估测混池抽取的出货率以及让各位旅行者可以过手瘾&#xff0c;故开发了此项目作为参考。 创作说明&am…

【C++】C++中的stack和queue

一、概述 本篇blog写明了介绍的是STL(标准模板库)中的stack和queue&#xff0c;栈和队列虽然在处理数据的方式上有明显的不同&#xff0c;但它们作为操作受限的线性数据结构&#xff0c;在学习和应用中经常被放在一起讨论&#xff0c;以便更全面地理解数据结构的概念和使用。 在…

VMware ESXi 6.7

1.浏览器中输入地址&#xff0c;进入管理界面 2.选择 存储 右击浏览&#xff0c;创建新的目录 3.点击 上载 &#xff0c;选择镜像文件 4.等待上载完成 5.点击 虚拟机-新建虚拟机 6.进入新建虚拟机界面 7.进入Windows安装界面 8.安装VMware Tools

AI头像背景替换多功能图片编辑器

本软件运用AI技术&#xff0c;可以轻松修改人像衣着外观与背景环境&#xff0c;支持图片延伸功能&#xff0c;还原度自然。同时也支持扣图及替换背景&#xff0c;图像特效处理和动画渲染等功能&#xff0c;是很推荐的一款图像处理软件。 软件介绍&#xff1a; 它是一款…

归并排序详解(非递归)

感谢各位大佬的光临&#xff0c;希望和大家一起进步&#xff0c;望得到你的三连&#xff0c;互三支持&#xff0c;一起进步 个人主页&#xff1a;LaNzikinh-CSDN博客 收入专栏&#xff1a;http://t.csdnimg.cn/LJ2J2 文章目录 前言一.归并排序二.代码实现归并排序&#xff08;递…

【6】单向循环链表

【6】单向循环链表 1、单向循环链表2、add(int index, E element)3、删除 1、单向循环链表 &#x1f58a; 在单向链表的基础上&#xff0c;尾节点的 next 指向头节点 2、add(int index, E element) &#x1f58a; 往尾部添加的代码不用修改&#xff08;和单向链表一样的&am…

华为ensp中基本acl 原理及配置命令(详解)

作者主页&#xff1a;点击&#xff01; ENSP专栏&#xff1a;点击&#xff01; 创作时间&#xff1a;2024年4月5日10点45分 基本ACL的简介 华为ensp中的基本acl是指华为设备中用于控制网络访问的访问控制列表的其中一种类型。基本acl可以根据数据包的源IP地址进行过滤&#…

备战蓝桥杯---多路归并与归并排序刷题

话不多说&#xff0c;直接看题 1. 我们考虑一行一行合并&#xff0c;一共m次&#xff0c;我们合并两个并取前n小&#xff0c;那么我们怎么取&#xff1f; 我们采用分组的思想&#xff1a; 我们选第一列的min,然后把后面那个再纳入考虑&#xff0c;用优先队列实现即可。 下面…

今年考研是太卷了还是太水了,为什么分数线都高的离谱?

25考研的备考形势&#xff0c;势必跟以前不一样了&#xff01; 有些人问&#xff0c;分数线那么高&#xff0c;是不是题目太水了&#xff1f; 问的人肯定不是24考生。 24的题&#xff0c;也就政治正常一点。 其它的&#xff0c;英语难上热搜&#xff0c;数学难度空前&#x…

04---webpack编写可维护的构建配置

01 构建配置抽离成npm包&#xff1b; 意义&#xff1a;通用性&#xff1a; 业务开发者无需关注构建配置 统一团队构建脚本可维护性&#xff1a;构建配置合理的拆分 质量&#xff1a;冒烟测试 单元测试 持续集成构建配置管理的可选方案&#xff1a;1 通过多个配置文件管理不同…

一、OpenCV(C#版本)环境搭建

一、Visual Studio 创建新项目 二、选择Windows窗体应用&#xff08;.NET Framework&#xff09; 直接搜索模板&#xff1a;Windows窗体应用(.NET Framework) 记得是C#哈&#xff0c;别整成VB(Visual Basic)了 PS&#xff1a;若搜索搜不到&#xff0c;直接点击安装多个工具和…