linux信号机制[一]

目录

信号量

时序问题

原子性

什么是信号

 信号如何产生

引入

信号的处理方法

常见信号

如何理解组合键变成信号呢? 

如何理解信号被进程保存以及信号发送的本质?

为什么要有信号

信号怎么用?

样例代码

core文件有什么用呢?

验证core的状态

 一般生产环境为什么要关闭core

kill:结束进程

软件条件产生的信号 

硬件产生的信号

如何理解除0错误

如何理解野指针和越界问题


由于临界区,和临界资源的存在,在进入临界区访问呢临界资源的时候,必须要先申请一个信号量。通知临界区,提前预定访问临界资源。对临界资源访问的预定。只有我这个进程访问完成之后其他的资源才可以访问呢。

信号量
时序问题

信号量本质上是一个计数器。

假有一个变量n = 6需要多次--,多个进程执行

cpu执行指令的时候,将内存中的数据加载到cpu内部的寄存器中(读指令),之后(n--)分析执行命令,然后将cpu修改之后的数据写回内存。进程在执行的时候任何时候都可能被切换。寄存器只有一套,被所有执行流共享,但是寄存器数据是单独的,属于执行流的上下文。

假设一个进程刚对n执行--到5然后结果没写入,被切换了,然后其他的进程对n--到0,写回去结果,此刻之前的进程继续执行,将5写回去,这回导致之前的进程工作白费。这就引出了时序问题。这种执行是不安全的。 

原子性

为了保证避免时序问题,就需要保证,每个临界资源,被访问,只能一个进程执行完,另一个进程继续执行。这种就叫做原子性。

什么是信号

首先信号和信号量是2个东西。linux信号本质上是一中通知机制,用户或者操作系统通过发送一定的信号。通知进程,某些事件已经发生,你可以在进行后续处理。结合进程,我们可以得出以下结论:

a.进程必须有识别进程的能力

b.为什么能识别信号呢?通过程序员的逻辑处理

c.信号到来是随机的,进程可能在忙自己的事情,信号的后续处理,可能不是立即处理的。(就像打游戏时候外卖送过来)。

d.信号会被临时记录下对应的信号,方便后续的处理。

e.在什么时候处理呢?合适的时候

 f.一般而言信号的产生和进程都是异步的。

 信号如何产生
引入

当一个程序运行的时候,我们在键盘上按ctrl + c本质上就是通过键盘组合向目标发送2号信号。让程序结束。

信号的处理方法

a.默认  每个信号都有默认的信号处理方法。(进程自带的)

b.忽略(也是信号的一种处理方式)

c.自定义(捕捉信号,自己处理)

常见信号
kill -l 此命令查看所有信号

 1-31为普通信号,没有0号32,33号信号。34-64是实时信号。我们一般只关心1-31.

我们使用 man 7 signal 查看

里面有一个action 默认处理行为。

如何理解组合键变成信号呢? 

键盘的工作方式是通过中断方式进行的,可以识别组合键。操作系统解释组合键,查找进程列表找到相关的进程,修改内部数据结构。

如何理解信号被进程保存以及信号发送的本质?

为了识别信号,进程必须保存信号相关的信号数据结构。怎么表示呢?位图。pcb内部保存了信号位图字段。

信号位图是在task_struct里面保存的。发送信号的时候操作系统修改pcb内部位图字段。也就是说发信号,本质上就是修改操作系统内部指定的位图结构,完成发送信号的过程。

为什么要有信号

a.是什么信号

b.是否产生

信号怎么用?

介绍一个函数

#include <signal.h>typedef void (*sighandler_t)(int);sighandler_t signal(int signum, sighandler_t handler);

这个函数可以对信号进行自定义。参数1是对哪个信号进行捕捉,信号的类型,参数二是函数指针,回调函数。通过回调的方式,修改信号的处理方法。

样例代码
#include<iostream>
#include<signal.h>
#include<sys/types.h>
#include<unistd.h>
using namespace std;//信号捕捉
void catchsig(int sigum)
{cout<<"捕捉到了信号:"<<sigum<<"pid:"<<"getpid()"<<endl;
}int main()
{//SIGINT是二号信号,在用户输入ctrl信号时发出。用于通知前台结束进程signal(SIGINT,catchsig);//也可以直接写数字名字都可以,第一个参数是信号处理选项//信号的处理方法一般只有一个signal(SIGQUIT,catchsig);//二号和三号信号捕捉。//signal仅仅是修改进程对特定信号处理方法,而不是直接调用处理方法while(1){//加循环是为了给信号产生留下时间cout<<"我是一个进程在运行。。。pid:"<<getpid()<<endl;sleep(1);}return 0;
}

在之前我们查看信号的时候action里面有2个选项term 和 core

那么core是什么呢?core全程core dump核心转储标志,表示是否发送核心转储。一般而言核心转储是被关闭的。

首先解释什么是Core Dump。当一个进程要异常终止时,可以选择把进程的用户空间内存数据全部保存到磁 盘上,文件名通常是core,这叫做Core Dump。进程异常终止通常是因为有Bug,比如非法内存访问导致段错误, 事后可以用调试器检查core文件以查清错误原因,这叫做Post-mortem Debug(事后调试)。一个进程允许 产生多大的core文件取决于进程的Resource Limit(这个信息保存 在PCB中)。默认是不允许产生core文件的, 因为core文件中可能包含用户密码等敏感信息,不安全。在开发调试阶段可以用ulimit命令改变这个限制,允许 产生core文件。 首先用ulimit命令改变Shell进程的Resource Limit,允许core文件最大为1024K:

ulimit -a

 这个命令可以查看服务器状态,里面会显示core的状态。

可以使用ulimit  -c 1024命令打开core状态,并指定core为1024字节。如果我们使用带有 core的信号的时候例如8号信号结束程序,程序会结束时带有core.并且生成core文件,以自己的pid为结尾。

core文件有什么用呢?

当进程出现异常的时候,由系统将当前进程内存中的核心数据dump到磁盘中。也就是core文件。

那么为什么要转储呢?——调试。

在使用调试生成文件之后使用gdb进行调试 core-file加载定位文件。可以直接定位到出错位置。

验证core的状态

    int status =0;waitpid(id,&status,0);cout<<"父进程"<<getppid()<<"子进程"<<getpid()<<" 退出码:"<< status&0x7f<<"是否 core"<<(status>>7&1)<<endl;
 一般生产环境为什么要关闭core

生产环境内存空间有限,因为有时候服务可能不可抗力导致一直重启,一直生产core文件,极有可能塞满内存空间出问题。

信号接口

kill:结束进程

#include <signal.h>

int kill(pid_t pid, int signo);

向指定进程发送指定信号。

int raise(int signo); 这两个函数都是成功返回0,错误返回-1

自己给自己发送自己定义的信号。

#include

void abort(void);

就像exit函数一样,abort函数总是会成功的,所以没有返回值。  自己终止自己。想当于自己给自己发6号信号

系统调用本质上也就是操作系统,修改对应的数据结构。

软件条件产生的信号 

管道——独端不读,而且一直写,会发生什么?系统会自动终止通过发送信号的方式SIGPIPE.

include <unistd.h>

unsigned int alarm(unsigned int seconds); 调用alarm函数可以设定一个闹钟,也就是告诉内核在seconds秒之后给当前进程发SIGALRM信号, 该信号的默认处理动 作是终止当前进程。

#include<iostream>
#include<sys/types.h>
#include<unistd.h>
#include<sys/wait.h>
using namespace std;
#include<signal.h>
#include<string>int main()
{alarm(1);int count =0;while(1){cout<<"cout :"<<count++<<endl;}}

 这个代码是计算一秒钟count++了多少次

虽然这个数很大但是,相比于cpu的性能其实很拉跨,这是为什么呢?

cout大量IO很消耗时间,还有网络传输发送,导致非常慢。

闹钟有一个问题,一旦使用过就会自动移除。那么闹钟如果想要周期性的使用怎么办呢?

就需要信号捕获之后在处理方法中重新设定闹钟。

硬件产生的信号

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

如何理解除0错误

数据在cpu上进行计,cpu上由寄存器,其中有一种状态寄存器。有对应的状态标记位,如果发生错误,os会自动进行计算之后的检测。这个状态是由cpu执行的,由操作系统检测。而出现硬件异常一般会打印消息然后退出。但是不退出也不是不行,不过即使不退出也没什么用。信号捕捉之后如果发生死循环这是,此刻的寄存器还是处于错误状态,没有进行复位。

如何理解野指针和越界问题

都必须通过地址,找到目标位置,语言上的地址都是虚拟地址,将语言上的虚拟地址转换成物理地址。页表+MMU(硬件),找到地址。而野指针,和越界,在mmu转化的时候一定会报错。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker基础与持续集成

docker 基础知识&#xff1a; docker与虚拟机 !左边为虚拟机&#xff0c;右边为docker环境 – Server :物理机服务器Host OS &#xff1a;构建的操作系统Hypervisor &#xff1a;一种虚拟机软件&#xff0c;装了之后才能虚拟化操作系统Guest OS &#xff1a;虚拟化的操作系统…

自动驾驶轨迹规划之kinodynamic planning

欢迎大家关注我的B站&#xff1a; 偷吃薯片的Zheng同学的个人空间-偷吃薯片的Zheng同学个人主页-哔哩哔哩视频 (bilibili.com) 本文PPT来自深蓝学院《移动机器人的运动规划》 目录 1.kinodynamic的背景 2. old-school pipline 3.example 1.kinodynamic的背景 kinodynami…

java之jvm详解

JVM内存结构 程序计数器 Program Counter Register程序计数器(寄存器) 程序计数器在物理层上是通过寄存器实现的 作用&#xff1a;记住下一条jvm指令的执行地址特点 是线程私有的(每个线程都有属于自己的程序计数器)不会存在内存溢出 虚拟机栈(默认大小为1024kb) 每个线…

LeetCode、739. 每日温度【中等,单调栈】

文章目录 前言LeetCode、739. 每日温度【中等&#xff0c;单调栈】题目链接及分类思路单调栈 资料获取 前言 博主介绍&#xff1a;✌目前全网粉丝2W&#xff0c;csdn博客专家、Java领域优质创作者&#xff0c;博客之星、阿里云平台优质作者、专注于Java后端技术领域。 涵盖技…

二次元自适应动态引导页

源码介绍 二次元自适应动态引导页&#xff0c;HTMLJSCSS&#xff0c;记事本修改&#xff0c;上传到服务器即可&#xff0c;也可以本地双击index.html查看效果 下载地址 https://wfr.lanzout.com/isRem1o7bfcb

MockServer 服务框架设计

大部分现有的 mock 工具只能满足 HTTP 协议下简单业务场景的使用。但是面对一些复杂的业务场景就显得捉襟见肘&#xff0c;比如对 socket 协议的应用进行 mock&#xff0c;或者对于支付接口的失败重试的定制化 mock 场景。 为解决上述问题&#xff0c;霍格沃兹测试学院设计并研…

零基础学编程怎么入手,中文编程工具构件箱之多页面板构件用法教程,系统化的编程视频教程上线

零基础学编程怎么入手&#xff0c;中文编程工具构件箱之多页面板构件用法教程&#xff0c;系统化的编程视频教程上线 一、前言 今天给大家分享的中文编程开发语言工具资料如下&#xff1a; 编程入门视频教程链接 http://​ https://edu.csdn.net/course/detail/39036 ​ …

下一代块存储重新定义任务关键型存储架构

HPE 宣布全面推出基于 HPE Alletra Storage MP 构建的 HPE GreenLake for Block Storage 第 3 版&#xff0c;提供业界首款分解式横向扩展块存储&#xff0c;并提供 100% 数据可用性保证。这种独特的块存储产品由共享一切存储架构提供支持&#xff0c;并通过 HPE GreenLake 云平…

(算法3)二分查找

朴素二分查找 最直接的二分查找&#xff0c;有序&#xff0c;查找数组中的某个元素 这种方法是有局限性的&#xff1a;只可以查找升序的数组&#xff0c;且要查找的元素是一个 注意&#xff1a;mid(中点&#xff09;的计算应该是&#xff1a;left(right-left)/2 (个数是偶数时…

接口测试06 -- pytest接口自动化封装Loggin实战

1. 接口关键字封装 1.1 基本概念 接口关键字封装是指:将接口测试过程中常用的操作、验证封装成可复用的关键字(或称为函数、方法),以提高测试代码的可维护性和可复用性。 1.2 常见的接口关键字封装方式 1. 发送请求:封装一个函数,接受参数如请求方法、URL、请求头、请求…

基于Spring Boot的美容院管理系统设计与实现,计算机毕业设计(带源码+论文)

源码获取地址&#xff1a; 码呢-一个专注于技术分享的博客平台一个专注于技术分享的博客平台,大家以共同学习,乐于分享,拥抱开源的价值观进行学习交流http://www.xmbiao.cn/resource-details/1757434902285987841

洛谷数组P1319压缩技术

做题思路&#xff1a; 这里表示输入的第一个数字N为N*N的方阵&#xff0c;后面的数字表示连续输入几个1或者0&#xff0c;定义result表示实际输出的数字0或1&#xff08;result输出0或1&#xff0c;可以用绝对值abs我们初始化result为0&#xff0c;我们将它-1后再取绝对值就可以…

二、ClickHouse简介

ClickHouse简介 前言一、行式存储二、DBMS功能三、多样化引擎四、高吞吐写入能力五、数据分区与线程级并行六、场景七、特定版本 前言 ClickHouse 是俄罗斯的 Yandex 于 2016 年开源的列式存储数据库&#xff08;DBMS&#xff09;&#xff0c;使用 C 语言编写&#xff0c;主要…

[NSSCTF]-Web:[SWPUCTF 2021 新生赛]easyrce解析

先看网页 代码审计&#xff1a; error_reporting(0); &#xff1a;关闭报错&#xff0c;代码的错误将不会显示 highlight_file(__FILE__); &#xff1a;将当前文件的源代码显示出来 eval($_GET[url]); &#xff1a;将url的值作为php代码执行 解题&#xff1a; 题目既然允许…

片上网络NoC(4)——直连拓扑

目录 一、前言 二、直连拓扑 三、总结 一、前言 本文中&#xff0c;我们将继续介绍片上网络中拓扑相关的内容&#xff0c;主要介绍直连拓扑&#xff0c;在此之前&#xff0c;我们已经介绍过了拓扑的指标&#xff0c;这将是继续阅读本文的基础&#xff0c;还没有了解相关内容…

算法刷题:盛水最多的容器

盛水最多的容器 .习题链接题目题目解析算法原理我的答案 . 习题链接 盛水最多的容器 题目 题目解析 VH*W h为左右两边低的一边,w为左右两边之间的距离 算法原理 定义两个指针 left0,rightn-1; left从左往右对数组进行遍历,right从右往左进行遍历 遍历的过程中,每一次都需要…

Hive的小文件问题

目录 一、小文件产生的原因 二、小文件的危害 三、小文件的解决方案 3.1 小文件的预防 3.1.1 减少Map数量 3.1.2 减少Reduce的数量 3.2 已存在的小文件合并 3.2.1 方式一&#xff1a;insert overwrite (推荐) 3.2.2 方式二&#xff1a;concatenate 3.2.3 方式三&#xff…

全国计算机等级考试二级,MySQL数据库考试大纲(2023年版)

基本要求&#xff1a; 1.掌握数据库的基本概念和方法。 2.熟练掌握MySQL的安装与配置。 3.熟练掌握MySQL平台下使用&#xff33;&#xff31;&#xff2c;语言实现数据库的交互操作。 4.熟练掌握 MySQL的数据库编程。 5.熟悉 PHP 应用开发语言&#xff0c;初步具备利用该语言进…

中小学信息学奥赛CSP-J认证 CCF非专业级别软件能力认证-入门组初赛模拟题第二套(选择题)

CSP-J入门组初赛模拟题二 1、在计算机内部用来传送、存贮、加工处理的数册或指令都是以()形式进行的 A、二进制 B、八进制 C、十进制 D、智能拼音 答案&#xff1a;A 考点分析&#xff1a;主要考查小朋友们计算机相关知识&#xff0c;在计算机中都是采用二进制运算&#…

助力工业生产质检,基于轻量级yolov8-seg开发构建工业场景下滚珠丝杠传动表面缺陷分割检测系统

AI赋能工业生产是一个强有力的方式&#xff0c;在我们之前的系列博文中也有很多相应的开发实践&#xff0c;感兴趣的胡都可以自行移步阅读&#xff0c;本文的核心思想就是想要基于轻量级的实例分割模型来开发构建工业场景下的滚珠丝杠传动表面缺陷分割检测系统&#xff0c;首先…