Linux系统之信号及处理流程(图详解)

关于Linux系统(信号篇)

  • 引言:信号机制是一种使用信号来进行进程之间传递消息的方法,信号的全称为软中断信号,简称软中断。信号的本质是软件层次上对中断的一种模拟(软中断)。它是一种异步通信的处理机制,事实上,进程并不知道信号何时到来。Linux系统一共有64个信号,其中1-31信号供应用开发者使用
    34-64信号供驱动开发者使用,如图。
    在这里插入图片描述
  1. 信号是什么?
    信号是由用户、系统或进程发送给目标进程的信息,以通知目标进程摸个状态的改变或系统异常。

*信号处理的优先级是大于系统调用的。

  • 看几种常用的信号
    在这里插入图片描述
    大部分常见信号的默认处理方式其实都是终止进程,之所以分成这么多种信号,是为了让进程知道具体是哪个信号,从而判断对应发生的事件。
  • 什么是core文件?
    core文件是在进程收到终止信号并终止程序时,保存当前进程代码和数据的二进制文件,但在实际应用开发中也很少会去查看该文,所以系统默认是不创建该文件,在结束进程时会出现core dumped。
  1. 信号都会有系统默认处理方式,既然有默认那么就说明它的处理方式能修改
  • 信号的三种处理方式:默认、忽略、捕获

  • [ 默认] :进程收到该信号,按照系统默认方式处理。

  • [ 忽略]: 进程直接忽略此信号,对进程没有影响。

  • [ 捕获]: 进程收到信号,则处理用户自定义的捕获函数,而之前的默认处理方式失效。
    修改信号处理方式的函数 :在这里插入图片描述在这里插入图片描述
    SIG_IGN为忽略,SIG_DFL为默认。

捕获效果:
在这里插入图片描述
在这里插入图片描述

其中SIGINT信号是通过ctrl+c发送给运行在当前窗口的前台进程的,用signal设置此信号的处理方式为捕获,捕获函数为fun。
当信号发送时,即使主进程还在执行任务,也会被系统中断来执行捕获函数,捕获函数结束后,进程会回到上次执行的地方。

3.信号处理流程
在这里插入图片描述
4.相关api

//设置变量的值
#include<signal.h>
int sigemptyset(sigset_t *set); //将set变量的64位全部设置为0
int sigfillset(sigset_t *set); //将set变量64为全部设置为1
int sigaddset(sigset_t *set ,int signum); //将信号编号那位设置为1,其他不变
int sigdelset(sigset_t *set ,int signum); //将信号编号那位设置为0,其他不变
//返回值:成功返回0,失败返回-1
//使用变量修改信号屏蔽字
#include<signal.h>

int sigprocmask(int how , const sigset_t *set ,sigset_t *oldset);
/*how:修改方式,SIG_BLOCK--屏蔽某个信号
				SIG_UNBLOCK:打开某个信号
				SIG_SETMASK:直接用set参数替换掉整个屏蔽字
 set:传入设置好的信号集
 oldset:传出修改之前的屏蔽字的值,如果为NULL,表示不保存
*/

代码实现:
在这里插入图片描述
在这里插入图片描述

解释:首先让该进程屏蔽SIGINT信号,即信号屏蔽字对应SIGINT位置1,等到接收到此信号时就将其放到未决信号集,2s之后,该进程取消屏蔽SIGINT信号,这时内核去检查未决信号集对应的SIGINT位是否有信号,如果有,那么处理该信号,所以会看到0s以后会打印一个hello,但再睡眠期间有两个SIGINT信号发来,但等到第二个来的时候未决信号集已经置1了,所以第二个被忽略,之后的SIGINT信号就正常接收了。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Linux内核的启动流程可以分为以下几个步骤: 1. 入口点确定:在链接文件vmlinux.lds中,通过ENTRY(stext)可以找到Linux内核的入口点,即stext。stext定义在arch/arm/kernel/head.S文件中。 2. 初始化设置:内核入口点stext首先会执行一些初始化设置,例如设置中断向量表、设置栈指针等。 3. 启动内核:接下来,stext会调用start_kernel函数,这是Linux内核的入口函数。start_kernel函数主要完成一些基本的系统初始化工作,例如初始化内核数据结构、设置页表等。 4. 创建init进程:在start_kernel函数中,会调用kernel_thread函数创建kernel_init进程,也就是init内核进程。init进程的PID为1。init进程最初是运行在内核态的,然后它会在根文件系统中查找名为"init"的程序,并通过运行这个程序实现从内核态到用户态的转变。 5. 初始化子系统:接下来,init进程会开始初始化各个子系统,例如内存管理子系统、进程管理子系统、设备驱动子系统等。每个子系统都有相应的初始化函数,用来初始化子系统的数据结构、注册设备驱动等。 6. 启动用户空间:在初始化子系统完成后,init进程会启动用户空间的第一个进程,通常是/bin/init或/sbin/init。这个进程会执行系统的初始化脚本,加载其他用户进程,并开始运行用户程序。 总之,Linux内核的启动流程包括入口点确定、初始化设置、启动内核、创建init进程、初始化子系统和启动用户空间等步骤。通过这些步骤,Linux内核能够完成系统的初始化和用户程序的加载,实现整个系统的正常运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

长不大的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值