Linux 第三十章

🐶博主主页:@ᰔᩚ. 一怀明月ꦿ 

❤️‍🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C++,linux

🔥座右铭:“不要等到什么都没有了,才下定决心去做”

🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀

目录

信号量

如何理解信号量

信号 

信号的概念

信号的产生

singal

信号种类

0-31是普通信号

通过系统调用实现信号产生

Kill系统调用

raise

abort

异常发送信号

软件条件产生异常

alarm


信号量

信号量的本质是一把“计数器”

多个执行流(进程)看到的同一份资源,其实就是公共资源(由os提供的),如果并发访问同一份资源,会导致数据不一致的问题,我们就应该对公共资源进行保护,可以利用可同步和互斥(在多线程的时候着重理解)来解决。

互斥:任何时刻只允许一个执行流(进程)访问公共资源,加锁实现的

同步:多个执行流(进程)执行的时候,按照一定顺序执行,条件变量实现

被保护起来的公共资源,临界资源

访问临界资源的代码,临界区

非临界资源

非临界区

维护临界资源,其实就是在维护临界区

原子性:只有2两种状态,要么做,要么不做

如何理解信号量

信号量:表示资源数目的计数器,每一个执行流(进程)想要访问公共资源内的某一份资源,不应该让执行流(进程)直接访问,而是先申请信号量资源,其实就是先对信号量计数器进行--操作。本质上--就完成了,对资源的预定机制

如果申请不成功?我们的执行流(进程)被阻塞,等到申请成功

申请信号量资源是--

释放信号量资源是++

二元信号量:起到了互斥的效果(因为信号量资源只有一份),互斥锁

1.意味着,每一个进程都先看到同一个信号量资源
2.信号量本质也是公共资源
3.单个信号量
struct sem
{
    Int count;
    Task_strct* wait_queue
}

信号 

信号的概念

生活中的信号

红绿灯、下课铃声、狼烟、闹钟等等

我(进程)为什么知道信号呢?肯定我(进程)之前就了解过信号

信号没有产生的时候,其实我(进程)已经能够知道,怎么处理这个信号

信号的到来,我(进程)并清楚具体什么时候,信号到来相对于我(进程)正在做的工作,是异步产生的

信号产生了,我(进程)不一定立即处理它,而是我(进程)在合理的时候处理

我(进程)必须要一种能力,将已经到来的信号进行暂时保存

什么叫做信号

信号是向目标进程发送通知消息的一种机制

异步

简单理解:在同一个时间下,一个进程做一个事情的时候,另一个进程也在做事情

信号的产生

进程在运行的时候
例:
前台运行:./myprocess
后台运行:./myprocess &

前台进程只能有一个,后台进程可以有多个

在 Linux 终端中,jobs 是一个命令用于显示当前终端会话中正在运行的作业(进程)。当你在终端上启动一个作业时,它将在前台或后台运行。使用 jobs 命令可以列出这些作业的状态和编号。
以下是一些与 jobs 命令相关的常用操作:
1. jobs:列出当前终端会话中正在运行的进程。每个进程都有一个编号,并且会显示进程状态(运行中、停止等)。
2. bg <job编号>:将一个停止的进程切换到后台运行。<job编号> 是通过 jobs 命令列出的进程编号。
3. fg <job编号>:将一个在后台运行的进程切换到前台运行。<job编号> 是通过 jobs 命令列出的进程编号。
4. Ctrl+Z:将当前正在前台运行的进程暂停,并将其放置到后台。可以使用 jobs 命令查看该进程的状态和编号。
5. Ctrl+C:终止当前正在前台运行的进程(不会终止shell)。

OS怎么知道键盘有数据输入呢?
通过硬件向CPU发送中断号,CPU就能够知道键盘有数据输入

信号本质其实就是用软件,来模拟中断的行为

键盘有两种数据输入:

1.普通数据

2.组合键的输入(^C、^Z等)

信号在合适的时候处理

1.默认行为(例如,生活中红灯时,需要我们等一等)

2.忽略行为

3.自定义的(例如,在等红灯的时候,唱歌)

singal

在 Linux 中,signal() 函数用于注册信号处理函数,

该函数原型如下:

#include <signal.h>
void (*signal(int signum, void (*handler)(int)))(int);
* signum 表示要捕获的信号编号,比如 SIGINT、SIGTERM 等。
* handler 是一个指向函数的指针,该函数负责处理接收到的信号。
signal() 函数的返回类型是一个函数指针,指向当前信号的处理函数。在调用 signal() 函数时,会将之前注册的信号处理函数(如果有的话)替换为新的处理函数,并返回之前注册的处理函数。

下面是一个简单的示例,演示如何使用 signal() 函数来捕获 SIGINT 信号并设置相应的处理函数:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void sigint_handler(int signum) {
    printf("Caught SIGINT signal, exiting...\n");
    exit(1);
}

int main() {
    // 注册 SIGINT 信号处理函数
    signal(SIGINT, sigint_handler);

    printf("Press Ctrl+C to send a SIGINT signal...\n");

    while (1) {
        // 进程持续执行
    }

    return 0;
}


在示例中,我们定义了一个名为 sigint_handler 的函数,用于处理接收到的 SIGINT 信号。然后,在 main() 函数中使用 signal() 函数注册了这个信号处理函数。当用户按下 Ctrl+C 发送 SIGINT 信号时,该处理函数将被调用。

需要注意的是,signal() 函数在一些情况下可能会有一些不确定的行为,因此推荐使用更加可靠和灵活的 sigaction() 函数来注册信号处理函数。

信号种类

1) SIGHUP       2) SIGINT       3) SIGQUIT      4) SIGILL       5) SIGTRAP
 6) SIGABRT      7) SIGBUS       8) SIGFPE       9) SIGKILL     10) SIGUSR1
11) SIGSEGV     12) SIGUSR2     13) SIGPIPE     14) SIGALRM     15) SIGTERM
16) SIGSTKFLT   17) SIGCHLD     18) SIGCONT     19) SIGSTOP     20) SIGTSTP
21) SIGTTIN     22) SIGTTOU     23) SIGURG      24) SIGXCPU     25) SIGXFSZ
26) SIGVTALRM   27) SIGPROF     28) SIGWINCH    29) SIGIO       30) SIGPWR
31) SIGSYS      34) SIGRTMIN    35) SIGRTMIN+1  36) SIGRTMIN+2  37) SIGRTMIN+3
38) SIGRTMIN+4  39) SIGRTMIN+5  40) SIGRTMIN+6  41) SIGRTMIN+7  42) SIGRTMIN+8
43) SIGRTMIN+9  44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9  56) SIGRTMAX-8  57) SIGRTMAX-7
58) SIGRTMAX-6  59) SIGRTMAX-5  60) SIGRTMAX-4  61) SIGRTMAX-3  62) SIGRTMAX-2
63) SIGRTMAX-1  64) SIGRTMAX 

信号既有名字,又有值,说明是用宏定义的

没有0号信号(用来标识进程正常退出)

信号一共62个信号,是从0-31和34-64

0-31是普通信号

* SIGHUP (1):挂起信号,通常用于重启进程。
* SIGINT (2):中断信号,通常由Ctrl+C发出,用于停止进程。
* SIGQUIT (3):退出信号,通常由Ctrl+\发出,用于强制终止进程。
* SIGILL (4):非法指令信号,通常由进程执行无效的机器指令而引起。
* SIGTRAP (5):陷阱信号,通常用于调试。
* SIGABRT (6):异常终止信号,通常由abort()函数发出,表示进程存在严重问题需要终止。
* SIGBUS (7):总线错误信号,通常由非法内存访问引起。
* SIGFPE (8):浮点异常信号,通常由除零或其他数学错误引起。
* SIGKILL (9):强制终止信号,无法被捕获、忽略或阻塞,用于强制杀死进程。
* SIGUSR1 (10):用户定义信号1。
* SIGSEGV (11):段错误信号,通常由非法内存访问引起。
* SIGUSR2 (12):用户定义信号2。
* SIGPIPE (13):管道破裂信号,通常发生在进程向已关闭的管道写入数据时。
* SIGALRM (14):定时器信号,通常由alarm()函数或setitimer()函数发出。
* SIGTERM (15):终止信号,通常用于请求进程正常停止。
* SIGSTKFLT (16):堆栈错误信号,通常发生在堆栈溢出时。
* SIGCHLD (17):子进程状态改变信号,通常用于父进程监控子进程的状态。
* SIGCONT (18):继续执行信号,通常用于恢复被停止的进程。
* SIGSTOP (19):停止信号,无法被捕获、忽略或阻塞,用于暂停进程。
* SIGTSTP (20):挂起信号,通常由Ctrl+Z发出,用于暂停进程。
* SIGTTIN (21):后台读取信号,通常发生在后台进程尝试从终端读取数据时。
* SIGTTOU (22):后台写入信号,通常发生在后台进程尝试向终端写入数据时。
* SIGURG (23):紧急数据可读信号,通常发生在带外数据到达时。
* SIGXCPU (24):CPU时间限制信号,通常发生在进程超过CPU时间限制时。
* SIGXFSZ (25):文件大小限制信号,通常发生在进程超过文件大小限制时。
* SIGVTALRM (26):虚拟定时器信号,通常由setitimer()函数发出。
* SIGPROF (27):CPU时间分配信号,通常由setitimer()函数发出。
* SIGWINCH (28):窗口大小改变信号,通常发生在终端窗口大小改变时。
* SIGIO (29):异步I/O信号,通常用于异步I/O操作。
* SIGPWR (30):电源故障信号,通常发生在电源故障时。
* SIGSYS (31):系统调用错误信号,通常由进程执行非法的系统调用而引起。

每一个进程都有一张自己的函数指针数组表,数组的下标就和信号编号相关的

对于普通信号来讲,进程收到信号之后,进程要表示自己是否收到了某种信号

怎么表示是否收到呢?

可以使用位图的方式:0000 0000
比特位的位置,决定信号编号
比特位的内容,决定是否收到信号
在进程控制块中,有一个字段就是位图
task_struct
{
    //信号位图
    uint32_t sigmap;
}

OS向目标进程发送信号,其实就是向目标进程pcb的位图写信号

注意:无论信号有多少种产生方式,永远只能让OS向目标进程发送(OS是进程的管理者)

每个进程与信号相关都两个字段

1.函数指针数组

2.信号位图

34-64是实时信号

ctrl+z:默认暂停进程

ctrl+\:默认是终止进程

signal系统调用可以自定义,信号的处理方法

man 7 signal可以查看信号的默认处理方法

注意,像9号等信号不能自定义信号的处理方法

通过系统调用实现信号产生

Kill系统调用

kill 系统调用的原型如下:

#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
其中,pid 参数指定要发送信号的目标进程的进程ID,sig 参数指定要发送的信号编号。

以下是 kill 系统调用的常见用法:
终止进程:使用 SIGKILL 信号(编号为9)可以强制终止指定进程。
kill(pid, SIGKILL);

请注意,kill 系统调用只能发送信号给具有合法权限的目标进程。此外,kill 系统调用返回0表示成功,返回-1表示出错,并设置相应的错误码。

raise

raise 是一个函数,用于向当前进程发送信号。它的原型如下:

#include <signal.h>
int raise(int sig);
其中,sig 参数指定要发送的信号编号。

使用 raise 函数,可以向当前进程发送指定的信号。例如,以下代码将向当前进程发送 SIGTERM 信号(请求进程优雅地终止):
raise(SIGTERM);
与 kill 系统调用不同,raise 函数只能向当前进程发送信号,不能向其他进程发送信号。此外,raise 函数返回0表示成功,返回非零值表示出错,通常是因为指定了无效的信号编号。

abort

abort 是一个函数,用于向当前进程发送 SIGABRT 信号并终止进程。它的原型如下:
#include <stdlib.h>
void abort(void);
abort 函数会向当前进程发送 SIGABRT 信号,该信号的默认处理方式是生成一个核心转储文件并终止进程。

abort 函数通常被用于在程序发生无法恢复的错误时,终止程序并生成一个核心转储文件以供调试分析。例如,在以下代码中,如果 malloc 函数返回空指针,我们可以使用 abort 函数终止程序并生成一个核心转储文件:
#include <stdlib.h>
void *ptr = malloc(size);
if (ptr == NULL) {
    fprintf(stderr, "Error: failed to allocate memory.\n");
    abort();
}
请注意,与 exit 函数不同,abort 函数不会调用已注册的退出处理程序,也不会关闭流或执行任何其他清理操作。因此,abort 函数应该谨慎使用,仅在必要时才使用。

异常发送信号

int a=10;
a/=0;

如果异常不做处理(杀掉该进程),os会一直调度该进程,然后又出异常,循环往复。

寄存器!=寄存器里内容(进程上下文)

进程中的程序异常,进程一定会退出吗?默认情况下会退出,如果用signal自定义信号处理方法的话,就不一定了

如果进程出异常,和我们的编译器还有关系吗?进程会被OS直接终止了

一般出异常,是没有办法去处理这个异常,一般出异常,我们会显示这个异常,让我们自己看到

软件条件产生异常

alarm

#include <unistd.h>
unsigned int alarm(unsigned int seconds);
调用alarm函数可以设定一个闹钟,也就是告诉内核在seconds秒之后给当前进程发SIGALRM信号, 该信号的默认处理动
作是终止当前进程,如果 seconds 参数为0,则之前设置的闹钟将被取消,并返回剩余的闹钟时间。


int main()
{
    alarm(1);
    int cnt=0;

    while(true)
    {
        cout<<"alarm: "<<cnt++<<endl;
    }
    return 0;
}

操作系统中的时间:

1.所有用户的行为,都是以进程的形式在OS中表现的

2.OS只要把进程调度好,就能完成所有的用户任务

3.CMOS,周期性,高频率的,向CPU发送时钟中断

OS本质就是一个死循环,操作系统的执行,是基于硬件中断的!!!

 🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸  

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu与Windows之间互传文件

Ubuntu与Windows之间互传文件 前言&#xff1a; 使用工具&#xff1a;FTP 客户端软件&#xff0c; FileZilla 下载地址如下&#xff1a;https://www.filezilla.cn/download 1、打开软件 2、建立连接 3、连接信息 4、如果连接不上可能是Ubuntu没有开启FTP 服务&#xff0c;先…

台服dnf局域网搭建,学习用笔记

台服dnf局域网搭建 前置条件虚拟机初始化上传安装脚本以及其他文件至虚拟机密钥publickey.pem客户端配置如果IP地址填写有误&#xff0c;批量修改IP地址 前置条件 安装有vmvarecentos7.6镜像&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/centos-vault/7.6.1810/isos/x86…

01-项目功能,架构设计介绍

稻草快速开发平台 开发背景就是通过此项目介绍使用SpringBoot Vue3两大技术栈开发一个拥有动态权限、路由的前后端分离项目&#xff0c;此项目可以继续完善&#xff0c;成为一个模板为将来快速开发做铺垫。 实现功能 开发流程 通过命令构建前端项目在VSCode中开发&#xff…

JavaScript数字(Number)个数学(Math)对象

目录 前言&#xff1a; Number&#xff08;数字&#xff09;对象 前言&#xff1a; nfinity(正负无穷大)&#xff1a; NaN&#xff08;非数字&#xff09;&#xff1a; Number的属性 Number的方法 构造函数 静态方法 实例方法 Math&#xff08;数学&#xff09;对象…

阿里天池基于LLM智能问答系统学习赛排到第一名了

阿里天池基于LLM智能问答系统学习赛排到第一名了 0. 引言1. 05-09分数排到第一名了 0. 引言 5.1 假期期间发现阿里天池基于LLM智能问答系统学习赛正好是我工作上用到的技术&#xff0c;就抱着玩一玩的心里挑战了一下。 这个比赛包含了text_comprehension&#xff08;RAG&…

【Linux】Linux安装JDK

一、卸载Linux自带的JDK #查询已有的JDK rpm -qa | grep jdk ①将查询到的JDK全部卸载掉 #直接复制一整行的JDK名称 yum -y remove java-1.7.0-openjdk-headless-1.7.0.261-2.6.22.2.el7_8.x86_64 ②卸载完第一个后再次查询 ③继续卸载&#xff0c;卸载完成后再次查询 ④查询…

2024 年中国大学生程序设计竞赛全国邀请赛(郑州)暨第六届CCPC河南省大学生程序 设计竞赛Problem L. Toxel 与 PCPC II

//sort bug下标 遍历dp. //没修负的bug肯定连续 #include<bits/stdc.h> using namespace std; #define int long long const int n1e611; int a,b,c[n],dp[n]; signed main() {ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);cin>>a>>b;for(int i1;…

高铁列车班组信息宣传投稿我喜欢上了这个好方法

作为高铁列车班组的一名工作人员,我肩负着对外信息宣传的重任。随着高铁列车的快速发展,我们班组不仅需要提供优质的服务,还需要通过媒体向外界传递我们的声音,展示我们的风采。然而,在投稿的过程中,我经历了一段充满挑战和困惑的时光。 起初,我采用传统的邮箱投稿方式,将精心撰…

基于Java的qq截图工具参考论文(论文 + 源码)

【免费】基于Java的qq截图工具.zip资源-CSDN文库https://download.csdn.net/download/JW_559/89304179 基于Java的qq截图工具 摘要 当今时代是飞速发展的信息时代&#xff0c;人们在对信息的处理中对图像的处理量与日俱增&#xff0c;这一点在文档人员上显得非常突出。 本软…

Hbase基础操作Demo(Java版)

一、前置条件 HBase服务&#xff1a;【快捷部署】023_HBase&#xff08;2.3.6&#xff09;开发环境&#xff1a;Java&#xff08;1.8&#xff09;、Maven&#xff08;3&#xff09;、IDE&#xff08;Idea 或 Eclipse&#xff09; 二、相关代码 代码结构如上图中①和② pom.x…

新消息:2024中国(厦门)国际义齿加工产品展览会

DPE2024中国&#xff08;厦门&#xff09;国际义齿加工产品展览会暨学术研讨会 2024 China (Xiamen) International Denture Processing Products Exhibition 时 间&#xff1a;2024年11月1-3日 November 1-3, 2024 地 点&#xff1a;厦门国际会展中心 Xiamen Int…

Llama3中文聊天项目全能资源库

Llama3 中文聊天项目综合资源库&#xff0c;集合了与Lama3 模型相关的各种中文资料&#xff0c;包括微调版本、有趣的权重、训练、推理、评测和部署的教程视频与文档。1. 多版本支持与创新&#xff1a;该仓库提供了多个版本的Lama3 模型&#xff0c;包括基于不同技术和偏好的微…

基于SpringBoot + Vue的扶贫助农管理系统设计与实现+毕业论文

系统介绍 系统分为用户和管理员两个角色 用户&#xff1a;登录、注册、论坛信息、查看扶贫公告信息、查看扶贫任务信息、报名任务、查看新闻信息&#xff08;新闻收藏、新闻留言&#xff09;、个人中心、在线客服等功能 管理员&#xff1a;登录、管理员管理、基础信息管理、客…

高考志愿系统-信息管理模块:院校信息分析

信息模块包括三个信息实体&#xff1a;招生学校&#xff0c;专业&#xff0c;分数线。 学校实体中有一个叫院校代码的属性&#xff0c;专业实体中含有院校代码这个属性&#xff0c;属于外键&#xff0c;一个学校有多个专业&#xff0c;所以学校和专业属于一对多关系。 专业实…

学习Uni-app开发小程序Day10

前面学习了局部组件的创建和简单使用&#xff0c;今天学习了slot&#xff08;插槽&#xff09;和组件之间的传值1. 插槽的使用 在components中&#xff0c;创建一个组件&#xff0c;给组件设置头部布局、内容布局、底部布局&#xff0c;例如&#xff1a; <template><…

数据科学:使用Optuna进行特征选择

大家好&#xff0c;特征选择是机器学习流程中的关键步骤&#xff0c;在实践中通常有大量的变量可用作模型的预测变量&#xff0c;但其中只有少数与目标相关。特征选择包括找到这些特征的子集&#xff0c;主要用于改善泛化能力、助力推断预测、提高训练效率。有许多技术可用于执…

Springboot整合 Spring Cloud Gateway

1.Gateway介绍 1.是spring cloud官方推出的响应式的API网关框架&#xff0c;旨在为微服务架构提供一种简单有效的API路由的管理方式&#xff0c;并基于Filter的方式提供网关的基本功能&#xff0c;例如&#xff1a;安全认证&#xff0c;监控&#xff0c;限流等等。 2.功能特征…

计算机网络学习记录 网络的大概认识 Day1

你好,我是Qiuner. 为记录自己编程学习过程和帮助别人少走弯路而写博客 这是我的 github gitee 如果本篇文章帮到了你 不妨点个赞吧~ 我会很高兴的 &#x1f604; (^ ~ ^) 想看更多 那就点个关注吧 我会尽力带来有趣的内容 计算机网络学习记录Day1 本文基于1.1 计算机网络在信息…

利用香港多IP服务器进行大数据分析的潜在优势?

利用香港多IP服务器进行大数据分析的潜在优势? 在当今数据驱动的时代&#xff0c;大数据分析已经成为企业获取竞争优势的不二选择。而香港作为一个拥有世界级通信基础设施的城市&#xff0c;提供了理想的环境来部署多IP服务器&#xff0c;从而为大数据分析提供了独特的优势。…

链动2+1结合消费增值:破解用户留存与复购的密码

大家好&#xff0c;我是吴军&#xff0c;来自一家领先的软件开发公司&#xff0c;担任产品经理的职务。今天&#xff0c;我希望能与大家深入交流链动21模式&#xff0c;特别是它在提升用户留存和复购率方面的独特价值。 虽然链动模式在某些人眼中可能被视为传统或已被超越&…