LIUNX系统编程:信号(3)

2024-06-07 23:36
文章标签 系统 编程 信号 liunx

本文主要是介绍LIUNX系统编程:信号(3),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

3.信号的处理

3.1信号是什么时候被处理的

read系统调用

3.2信号是怎样被处理的

内核态和用户态

 3.3操作系统是如何运行处理信号的呢?

中断技术

什么让操作系统运行起来的

3.4捕捉信号的其他方式

​编辑

demo代码


3.信号的处理

3.1信号是什么时候被处理的

信号在发送给进程之后不是立即处理的,而是等到合适的机会,在去处理信号的。

什么是合适的机会呢?

进程从内核态要切换回用户态时,会检测处理信号。

为什要内核态才能处理信号呢?

因为处理信号的时候一定会对内核数据结构做修改,就像在处理信号之前,要把pending表中信号对应的bit位置为0,然后去调用handler函数,处于用户态的时候是不允许让问内核数据的。

这里可能会有个问题,直接使用系统调用不就能对内核数据进行修改吗?还用上面说的来回切换多麻烦啊?

这是因为在执行系统调用的时候,也会切换到内核态的,举个例子。

read系统调用

1.将参数拷贝到内核

2.切换为内核态

3.在task_struct中找到文件描述符表。

4.访问0号fd的文件,将该文件的缓冲区拷贝到buffer中

5.将结果返回给用户。

6.返回用户态

信号的大致处理流程就是这样的。

但是自定义和默认处理方式流程是有区别的。

自定义处理:执行sighandler需要切换回用户态,去执行自定义的函数,然后返回内核态,内核态在返回运行结果给用户态。

默认处理:直接在内核态执行默认的sighandler函数,然后返回用户态即可。

 

3.2信号是怎样被处理的

内核态和用户态

进程的虚拟地址空间,分为用户区0-3g,和内核区3-4g,一共是4g。

这也就是为什么,进程总能找到操作系统,让操作系统替进程执行一些动作。

操作系统被映射到了,进程的地址空间内,经过mmu+页表将虚拟的地址转化为物理地址,就找到操作系统了。

内核级的页表只有一份,因为操作系统只有一个,操作系统的内核数据也只有一份,只需要一个内核级的页表,建立不同进程的虚拟地址到操作系统所处物理内存的映射,就可以让多个进程看到一个操作系统。

但是进程是有多个的,每个进程的数据也是不同的,这就需要不同的页表,来映射不同的进程。

 3.3操作系统是如何运行处理信号的呢?

首先呢操作系统是一个功能强大的傀儡,它没有自己的思想,得有人告诉操作系统要做什,它才会去做,不然操作系统什么都不会做。

中断技术

信号技术本质就是软件中断,软件中断就是对硬件中断的模拟。

 硬件中断:键盘直接连接到cpu的针脚上,当键盘输入的时候,会给对应的针脚一个高电频,cpu会拿着这个针脚的编号,去操作系统的中断向量表(函数指针数组),执行对应的函数。

软件中断:由软件产生一个中断信号,然后去操作系统的终端向量表,执行对应的函数。

重谈read方法

cs的寄存器的后两位是权限标识位。00代表是内核态,11代表用户态。

首先判断当前是不是用户态,是就把系统调用表中对应系统调用的编号放入eax寄存器中。

执行int 0x80指令陷入内核态,执行系统调用。

什么让操作系统运行起来的

操作系统是一个死循环,不断的接受其他外部的中断。

由一个硬件,向操作系统发送一个频率非常高,时间非常短的周期时钟中断,操作系统会拿着中断号去操作系统的中断向量表中,执行进程调度,内存管理,更新系统时间。。。任务。

3.4捕捉信号的其他方式

在处理信号的时候,会讲处理的信号屏蔽,防止一直接受同一个信号陷入循环。

参数:

signum是想要捕捉的信号,或者一些选项(不介绍)。

act:act是个结构体,含有一下内容。

        sa_handler是想要自定处理的函数

        sa_sigaction处理实时信号

        sa_mask除了屏蔽当前信号,还要屏蔽哪些信号。

        sa_flag是一些选项。

oldact:输出型参数,将原来信号的处理保存到oldact中。

demo代码

使用一下这个接口,屏蔽2号信号的同时屏蔽3,4,5号信号。

看下现象,运行起来的pending位图2,3,4,5的位置应该都是1。

验证

#include<signal.h>
#include<iostream>
#include<unistd.h>void print(sigset_t &pending)
{for(int i = 31; i >= 1; i--){if(sigismember(&pending,i)){std::cout<<"1";}else{std::cout<<"0";} }std::cout<<std::endl;
}void handler(int signo)
{//获取pending并打印sigset_t pending;sigemptyset(&pending);while(true){sigpending(&pending);//获取pending位图print(pending);//打印pendingsleep(1);}}int main()
{struct sigaction act,oact;act.sa_handler = handler;act.sa_flags = 0;sigemptyset(&act.sa_mask);//初始化信号集sigaddset(&act.sa_mask,3);//在信号集中添加3号信号sigaddset(&act.sa_mask,4);sigaddset(&act.sa_mask,5);sigaction(2,&act,&oact);//捕捉信号while(true)sleep(1);return 0;
}

第一次kill-2让信号被捕捉,第二次就直接被阻塞在pending位图中。

kill -3 -4 -5每次pending位图对应的位置都会变为1.

这篇关于LIUNX系统编程:信号(3)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1040618

相关文章

shell编程之函数与数组的使用详解

《shell编程之函数与数组的使用详解》:本文主要介绍shell编程之函数与数组的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录shell函数函数的用法俩个数求和系统资源监控并报警函数函数变量的作用范围函数的参数递归函数shell数组获取数组的长度读取某下的

利用Python快速搭建Markdown笔记发布系统

《利用Python快速搭建Markdown笔记发布系统》这篇文章主要为大家详细介绍了使用Python生态的成熟工具,在30分钟内搭建一个支持Markdown渲染、分类标签、全文搜索的私有化知识发布系统... 目录引言:为什么要自建知识博客一、技术选型:极简主义开发栈二、系统架构设计三、核心代码实现(分步解析

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

揭秘Python Socket网络编程的7种硬核用法

《揭秘PythonSocket网络编程的7种硬核用法》Socket不仅能做聊天室,还能干一大堆硬核操作,这篇文章就带大家看看Python网络编程的7种超实用玩法,感兴趣的小伙伴可以跟随小编一起... 目录1.端口扫描器:探测开放端口2.简易 HTTP 服务器:10 秒搭个网页3.局域网游戏:多人联机对战4.

Linux系统中卸载与安装JDK的详细教程

《Linux系统中卸载与安装JDK的详细教程》本文详细介绍了如何在Linux系统中通过Xshell和Xftp工具连接与传输文件,然后进行JDK的安装与卸载,安装步骤包括连接Linux、传输JDK安装包... 目录1、卸载1.1 linux删除自带的JDK1.2 Linux上卸载自己安装的JDK2、安装2.1

Java并发编程必备之Synchronized关键字深入解析

《Java并发编程必备之Synchronized关键字深入解析》本文我们深入探索了Java中的Synchronized关键字,包括其互斥性和可重入性的特性,文章详细介绍了Synchronized的三种... 目录一、前言二、Synchronized关键字2.1 Synchronized的特性1. 互斥2.

Linux系统之主机网络配置方式

《Linux系统之主机网络配置方式》:本文主要介绍Linux系统之主机网络配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、查看主机的网络参数1、查看主机名2、查看IP地址3、查看网关4、查看DNS二、配置网卡1、修改网卡配置文件2、nmcli工具【通用

Linux系统之dns域名解析全过程

《Linux系统之dns域名解析全过程》:本文主要介绍Linux系统之dns域名解析全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、dns域名解析介绍1、DNS核心概念1.1 区域 zone1.2 记录 record二、DNS服务的配置1、正向解析的配置

Python异步编程中asyncio.gather的并发控制详解

《Python异步编程中asyncio.gather的并发控制详解》在Python异步编程生态中,asyncio.gather是并发任务调度的核心工具,本文将通过实际场景和代码示例,展示如何结合信号量... 目录一、asyncio.gather的原始行为解析二、信号量控制法:给并发装上"节流阀"三、进阶控制

Linux系统中配置静态IP地址的详细步骤

《Linux系统中配置静态IP地址的详细步骤》本文详细介绍了在Linux系统中配置静态IP地址的五个步骤,包括打开终端、编辑网络配置文件、配置IP地址、保存并重启网络服务,这对于系统管理员和新手都极具... 目录步骤一:打开终端步骤二:编辑网络配置文件步骤三:配置静态IP地址步骤四:保存并关闭文件步骤五:重