【Linux】信号(二):信号的保存

发布于:2025-08-17 ⋅ 阅读:(18) ⋅ 点赞:(0)

一.信号保存方式

1.保存原理

信号保存原理其实在上篇信号(一)中,提到过保存的原理

我们linux中的信号
在这里插入图片描述
一共是1-31位,正好用32位大小的int整形来表示

原理其实就是这样

但是实际上肯定不是这么简单的,所以这篇博客就是来稍微深入了解下,Linux中的信号的保存形式

2.三表

Linux信号保存主要就是三个位图表
在这里插入图片描述

这里我们分别一个一个来讲作用

i.block

block表
在这里插入图片描述

这个表的作用是来设置信号屏蔽/阻塞

什么叫信号屏蔽/阻塞

就是当2信号在block表中被置1时,表示2信号被屏蔽
这个时候2信号不会被传递给进程

同时告诉系统,暂时不要处理这个号码的信号
Block表相当于是把这些信号暂时拉入了黑名单,

在OS传递给进程之前,就被拦了下来


ii.pending

在这里插入图片描述

这个表的是来记录信号是否被阻碍执行了

比如:
当block中有个2信号被屏蔽,然后系统发送了2信号
这个时候就会把pending中的2信号给置1,表示信号2发送过来,但被拦截了

因为屏蔽和是否发送是两回事
你是否屏蔽它,和它是否发送没有什么关系

Block就是告诉系统,暂时不要处理这个信号,但是发送的所以pending主要是记录待处理信息,你屏蔽到最后,还是要去执行这个信号的,所以说还是要再pending表中,把Block表中屏蔽的信号收到,也置为一


iii.handler

在这里插入图片描述
这个表本质是一个函数指针数组,记录了每个信号对应处理方法


二.信号保存设置接口

!!!改变方式!!!

我们了解基本的保存机制了
接下来就是使用接口了

首先我们要了解一点

操作系统从从来不信任用户

所以我们不能直接去改变系统中的这三个表

最后还是要通过:
系统允许你用的接口去调用改变

这里我们来了解一下block表的改变方法
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

大致就是这样,接下来来了解各个接口和具体过程

1.共同接口和变量

i.sigset_t

系统给你定义的类型,用来传递给位图改值的在这里插入图片描述

ii.sigemptyset()

这个作用是把sigset_t里面清空置0

在这里插入图片描述

iii.sigaddset()

在这里插入图片描述
这个接口的作用是:
位图set中的第signum个的信号置为一

在这里插入图片描述

2.三表设置接口

接下来就是改变三个表的接口了

三个表,分别由三个对应的接口,调用和改变
在这里插入图片描述

i.sigprocmask()

具体用法:

在这里插入图片描述

在这里插入图片描述

ii.sigpending()

我们知道pending本质上就是记录是否信号被拦截的的一个表

所以说我们没必要去改变什么
这个接口就是让我们去获取系统的pending表
在这里插入图片描述

iii.signal()

这个再前面一篇博客上讲过,可以去那边看看——信号【上】

3.使用实例

#include <signal.h>
#include<iostream>



void printpending(sigset_t & pend)
{
	for(int signo=31;signo>=1;signo--)
	{
		if(sigismember(&pend,signo))
		{
			std::cout<<"1";
		}
		else
		{
			std::cout<<"0";
		}
	
	}

		std::cout<<"\n\n";

}
int main()
{
	sigset_t s1;
	sigemptyset(&s1);
	sigaddset(&s1,2);
	sigprocmask(SIG_SETMASK,&s1,nullptr);

	while(true)
	{
		sigset_t pend;
		int n=sigpending(&pend);
		if(n<0)
		{
			continue;
		}
		printpending(pend);
		sleep(1);
	
	
	}



}

这里
1.把CTRL+C的2信号放进了block
2.不停打印pending表,查看拦截信号
3.发送CRTL+C表,查看是否被屏蔽和拦截
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到