当前位置: 首页 > news >正文

Linux 进程信号

进程信号

  • 1.信号的概念
    • 1.1 信号的定义
    • 1.2 生活中的信号
    • 1.3总结
  • 2. 进程信号的使用
    • 2.1 信号的种类
    • 2.2 信号的发送
      • 2.2.1 通过键盘发送信号
      • 2.2.2 通过系统调用发送信号
      • 2.2.3 软条件产生(alarm)
      • 2.2.4 硬件异常产生
  • 3. 信号的捕捉(signal函数)
  • 4. 信号阻塞
    • 4.1 相关概念
    • 4.2 信号在内核中的结构
  • 5. 内核中信号捕捉的过程

1.信号的概念

1.1 信号的定义

信号是进程之间事件异步通知的一种方式,属于软中断。

1.2 生活中的信号

当你在网上购买了商品时,你知道会有快递的到来,也知道该如何处理这个快递,所以这代表你可以识别信号。当快递到的时候,快递员会通知你下来拿快递,你可以立刻取也可以选择在合适的时间去取,也就是当信号来的时候不一定要立刻处理,但是你知道你有快递要取。当你拿到快递之后,对于快递的处理有三种方式。1.执行默认的动作(拆快递使用商品)2.自定义对该快递的使用(送人或扔掉都行)3.忽略该快递做自己的事情。纵观快递到来的整个过程对你其实是异步的,你在做你的事情。

1.3总结

  1. 信号只由操作系统发送给进程,进程是认识对应的信号的,对不同信号做出不同处理。
  2. 当信号到来的时候不一定要立刻处理。
  3. 由于第2点,表明信号需要存储起来,保存在PCB中。
  4. 对于信号的处理,进程有3中方式:默认、自定义、忽略。
  5. 发送信号的本质就是修改PCB中信号的位图结构。

2. 进程信号的使用

2.1 信号的种类

在这里插入图片描述
如上:1-31是普通信号,34-64是实时信号。而之后我们常用的是1-31的信号。

2.2 信号的发送

2.2.1 通过键盘发送信号

  1. ctrl + c:相当于上面的2号信号SIGINT,并且只对前台进程有效。
  2. ctrl + \ :相当于3号信号SIGQUIT。
  3. SIGINT的默认处理动作是终止进程,SIGQUIT的默认处理动作是终止进程并且Core Dump(进程终止后该文件保存该进程的信息,便于程序员调试)

2.2.2 通过系统调用发送信号

  1. kill函数(kill命令就是执行该函数,kill函数可以给任意指定的进程发送任意指定的信号)
    在这里插入图片描述

kill命令产生信号: kill -SIGKILL pid
返回值:
成功:0;失败:-1 (ID非法,信号非法,设置errno)
参数:
1.sig:中的任意一个发送给进程,表示你想要发送给某个进程的信号参数,可以选第1-第31个信号。
2.pid > 0:发送信号给指定的进程。(一般情况下都是这个) pid = 0:发送信号给 与调用kill函数进程属于同一进程组的所有进程
pid < 0:取 pid 发给对应进程组。 pid =-1:发送给进程有权限发送的系统中所有进程

  1. raise函数
    在这里插入图片描述

该函数返回值为int,返回值为0代表调用成功;返回非0则代表调用失败。
该函数是给本身进程发送任意信号。

  1. abort函数
    在这里插入图片描述

abort函数使当前进程接收到信号而异常终止,就像exit函数一样,abort函数总是会成功的,所以没有返回值。

2.2.3 软条件产生(alarm)

在这里插入图片描述

调用alarm函数可以设定一个闹钟,也就是告诉内核在seconds秒之后给当前进程发SIGALRM信号,该信号的默认处理动作是终止当前进程。
这个函数的返回值是0或者是以前设定的闹钟时间还余下的秒数。打个比方,某人要小睡一觉,设定闹钟为30分钟之后响,20分钟后被人吵醒了,还想多睡一会儿,于是重新设定闹钟为15分钟之后响,“以前设定的闹钟时间还余下的时间”就是10分钟。如果seconds值为0,表示取消以前设定的闹钟,函数的返回值仍然是以前设定的闹钟时间还余下的秒数。

2.2.4 硬件异常产生

硬件异常被硬件以某种方式被硬件检测到并通知内核,然后内核向当前进程发送适当的信号。例如当前进程执行了除以0的指令,CPU的运算单元会产生异常,内核将这个异常解释
为SIGFPE信号发送给进程。再比如当前进程访问了非法内存地址,MMU会产生异常,内核将这个异常解释为SIGSEGV信号发送给进程。

3. 信号的捕捉(signal函数)

前面不是说过信号可以自定义捕捉吗,就要使用到signal函数。
在这里插入图片描述

  1. signum参数是想要捕捉的某个信号,可以填指定的信号数字,也可以填信号的名称;
  2. handler参数是一个自定义的回调函数,在handler函数中可以将接收到信号做任意的处理。
  3. 该函数的作用:准备捕捉或屏蔽的信号由参数signum给出,接收到指定信号时将要调用的函数有handler给出
    注意:该函数不会阻塞,只有当信号到来的时候,才会调用该函数。
#include <stdio.h>
#include <signal.h>
void handler(int sig)
{printf("catch a sig : %d\n", sig);
}
int main()
{signal(2, handler);while(1);return 0;
}
[hb@localhost code_test]$ ./sig
^Ccatch a sig : 2
^Ccatch a sig : 2
^Ccatch a sig : 2
^Ccatch a sig : 2
^\Quit (core dumped)

我们在C/C++当中除零,内存越界等异常,在系统层面上,是被当成信号处理的。

4. 信号阻塞

4.1 相关概念

  1. 信号递达(Delivery):实际执行信号的处理方法。
  2. 信号未决(Pending):信号产生到递达之间的状态。(产生了但没处理)
  3. 操作系统可以阻塞某一信号。
  4. 阻塞一个信号之后,如果该信号产生,那么就会处于未决状态,而且在没解除阻塞之后永远不会递达。
  5. 注意,阻塞和忽略是不同的,只要信号被阻塞就不会递达,而忽略是在递达之后可选的一种处理动作。

4.2 信号在内核中的结构

在这里插入图片描述

  1. 每个信号都有两个标志位分别表示阻塞(block)和未决(pending),还有一个函数指针表示处理动作。信号产生时,内核在进程控制块中设置该信号的未决标志,直到信号递达才清除该标志。在上图的例子中,SIGHUP信号未阻塞也未产生过,当它递达时执行默认处理动作。
  2. SIGINT信号产生过,但正在被阻塞,所以暂时不能递达。虽然它的处理动作是忽略,但在没有解除阻塞之前不能忽略这个信号,因为进程仍有机会改变处理动作之后再解除阻塞。
  3. SIGQUIT信号未产生过,一旦产生SIGQUIT信号将被阻塞,它的处理动作是用户自定义函数sighandler。 如果在进程解除对某信号的阻塞之前这种信号产生过多次,将如何处理?POSIX.1允许系统递送该信号一次或多次。Linux是这样实现的:常规信号在递达之前产生多次只计一次,而实时信号在递达之前产生多次可以依次放在一个队列里。

5. 内核中信号捕捉的过程

1.进程在执行某条指令时由于中断、异常或者系统调用进入内核------->2.内核处理完成之后,进入用户态之前,内核会按照规则处理抵达的信号------->3.如果信号的处理是自定义,则回到用户态执行自定义的函数(注意不是主流程进入内核的那个地方)------->4.执行完成之后会执行特殊的系统调用sigretum从而进入内核态------->5.返回到主流程发生中断进入内核的地方继续执行。
在这里插入图片描述

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【JAVA基础】StringUtils.isEmpty、StringUtils.isBlank()、Objects.isNull()三者区别
  • 基因组学中的深度学习
  • C++学习笔记(8)
  • 单点登录及登录相关功能1
  • 代码随想录:279. 完全平方数
  • Qt 模仿企业微信图标实现按钮图片文字上下结构
  • MDC实现日志链路追踪
  • 高性能计算应用优化之代码实现调优(一)
  • TypeScript Agenda异常 undefined (reading ‘collection‘)
  • word中怎么快速选中光标之前或之后的全部内容?
  • 二、Maven工程的构建--JavaSEJavaEE
  • 软考高级:系统架构设计师——软件架构设计 Chapter 笔记
  • Redis持久化机制—RDB与AOF
  • 海外云手机是否适合运营TikTok?
  • GitLab管理之迁移GitLab群组
  • 【挥舞JS】JS实现继承,封装一个extends方法
  • CentOS6 编译安装 redis-3.2.3
  • Cookie 在前端中的实践
  • CSS3 聊天气泡框以及 inherit、currentColor 关键字
  • golang 发送GET和POST示例
  • iOS仿今日头条、壁纸应用、筛选分类、三方微博、颜色填充等源码
  • Java,console输出实时的转向GUI textbox
  • js数组之filter
  • leetcode388. Longest Absolute File Path
  • nginx 配置多 域名 + 多 https
  • PaddlePaddle-GitHub的正确打开姿势
  • SQLServer之索引简介
  • tensorflow学习笔记3——MNIST应用篇
  • vue脚手架vue-cli
  • yii2中session跨域名的问题
  • 不上全站https的网站你们就等着被恶心死吧
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 少走弯路,给Java 1~5 年程序员的建议
  • 温故知新之javascript面向对象
  • 小程序测试方案初探
  • 自动记录MySQL慢查询快照脚本
  • ​ 无限可能性的探索:Amazon Lightsail轻量应用服务器引领数字化时代创新发展
  • ​​​​​​​​​​​​​​汽车网络信息安全分析方法论
  • ######## golang各章节终篇索引 ########
  • #pragma once与条件编译
  • #微信小程序(布局、渲染层基础知识)
  • $.ajax中的eval及dataType
  • $forceUpdate()函数
  • (2015)JS ES6 必知的十个 特性
  • (4) PIVOT 和 UPIVOT 的使用
  • (6)STL算法之转换
  • (arch)linux 转换文件编码格式
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第2节(共同的基类)
  • (libusb) usb口自动刷新
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (附源码)springboot家庭财务分析系统 毕业设计641323
  • (九)信息融合方式简介
  • (篇九)MySQL常用内置函数
  • (三)docker:Dockerfile构建容器运行jar包
  • (微服务实战)预付卡平台支付交易系统卡充值业务流程设计