网站配色的原理和方法/最新实时新闻

网站配色的原理和方法,最新实时新闻,软文怎么优化网站,做自媒体发视频用哪些网站上篇文章:Linux操作系统5-进程信号1(信号基础)-CSDN博客 本篇Gitee仓库:myLerningCode/l25 橘子真甜/Linux操作系统与网络编程学习 - 码云 - 开源中国 (gitee.com) 本篇重点:信号的4种产生 目录 一. signal系统调用 …

上篇文章:Linux操作系统5-进程信号1(信号基础)-CSDN博客

本篇Gitee仓库:myLerningCode/l25 · 橘子真甜/Linux操作系统与网络编程学习 - 码云 - 开源中国 (gitee.com)

本篇重点:信号的4种产生

目录

一. signal系统调用

二. 产生信号的4种方式

2.1 终端按键产生信号

 2.2 系统调用/命令产生信号

a kill调用向其他进程发送信号

b raise向自己发送信号

2.3 硬件异常产生信号

a 除 0 异常

b 空指针解引用 

2.4 软件产生信号

a pipe 读端退出,写端立马退出

b alarm定时器产生信号 


一. signal系统调用

        signal系统调用可以帮助我们自定义信号的行为

//所需头文件
#include <signal.h>//函数原型    当进程收到signum这个信号之后,执行handler中的代码
typedef void(* sighandler_t)(int)    //函数指针
sighandler_t signal(int signum, sighandler_t handler);//参数说明
signum    需要自定义行为的信号编号
handler   自定义行为的函数//当某一个进程使用了signal系统调用之后,捕捉signum编号的信号就会执行下面的自定义行为
void handler(int signum)
{//由程序员自定义
}

举例代码:

我们自定义了2号信号的行为(ctrl c 发送的信号就是2号信号

#include <iostream>#include <unistd.h>
#include <signal.h>void handler(int signum)
{while(true){printf("进程[%d]收到信号[%d]\n",getpid(),signum);sleep(1);}
}int main()
{signal(2, handler);while (true){std::cout << "进程pid:" << getpid() << std::endl;sleep(1);}return 0;
}

        我们定义一个死循环的进程,并且自定义2号信号的行为。如果该进程收到2号信号那么他就会执行handler 中的死循环代码

测试结果如下:

我们输入ctrl c 来测试一下。

可以看到,输入ctrl c之后该进程收到2号信号。并且再次ctrl c 之后仍执行自定义行为的代码

注意:在我们调用signal之后并不会执行handler中的方法,而是在收到2号信号后再调用

二. 产生信号的4种方式

2.1 终端按键产生信号

常见的比如 ctrl c 向当前的前台进程发送2号信号,ctrl \ 向当前前台进程发送3号信号。

代码测试:

我们自定义2号和3号信号的行为来测试 ctrl c 和 ctrl \:

#include <iostream>#include <unistd.h>
#include <signal.h>void handler(int signum)
{while(true){printf("进程[%d]收到信号[%d]\n",getpid(),signum);sleep(1);}
}int main()
{//同时自定义2号信号和3号信号的行为signal(2, handler);signal(3, handler);while (true){std::cout << "进程pid:" << getpid() << std::endl;sleep(1);}return 0;
}

 2.2 系统调用/命令产生信号

        命令产生信号我们经常使用,就是 kill 信号 pid 即可向对应的进程发送对应的信号

a kill调用向其他进程发送信号

        kill不仅仅在命令中可以发送信号,也能在代码中使用

//头文件
#include <sys/types.h>
#include <signal.h>//函数原型
int kill(pid_t pid, int signum);//参数
向 pid 这个进程编号的进程发送 signum 这个编号的信号//返回值
成功返回0,失败返回-1,并且设置错误码

测试代码:

mykill.cpp

#include <iostream>
#include <sys/types.h>
#include <signal.h>void Usage(const std::string &proc)
{std::cout << "Usage\n"<< proc << "pid signum\n ";
}int main(int argc, char *argv[])
{if (argc != 3)Usage(argv[0]);pid_t pid = atoi(argv[1]);int signo = atoi(argv[2]);int n = kill(pid, signo);if(n < 0){std::cout << "kill error"<<std::endl;}return 0;
}

该代码通过命令行参数获取键盘输入的信息,解析后执行kill

test.cpp 

#include <iostream>#include <unistd.h>
#include <signal.h>void handler(int signum)
{while (true){printf("进程[%d]收到信号[%d]\n", getpid(), signum);sleep(1);}
}int main()
{// 同时自定义2号信号和9号信号的行为signal(2, handler);signal(3, handler);while (true){std::cout << "进程pid:" << getpid() << std::endl;sleep(1);}return 0;
}

可以看到,我们可以通过kill系统调用向其他进程发送信号

b raise向自己发送信号

#include <signal>int rasie(int sig);//给自己发送sig这个信号

测试代码:

通过raise向自己发送3号信号 

#include <iostream>#include <unistd.h>
#include <signal.h>void handler(int signum)
{while (true){printf("进程[%d]收到信号[%d]\n", getpid(), signum);sleep(1);}
}int main()
{// 同时自定义2号信号和9号信号的行为signal(3, handler);int cnt = 0;while (true){std::cout << "进程pid:" << getpid() << "[" << cnt++ << "]" << std::endl;if (cnt == 5)raise(3);sleep(1);}return 0;
}

测试结果:

可以看到,第5次的时候,收到3号信号执行自定义行为。

2.3 硬件异常产生信号

        信号不一定由用户发出,也有可能由OS发出。比如我们的 /0操作,越界访问操作。

a 除 0 异常

#include <iostream>
#include <string>#include <sys/types.h>
#include <signal.h>
#include <unistd.h>int main()
{// 3.硬件异常产生信号// 信号产生,不一定由用户显示发送。有可能由操作系统自动产生while (true){std::cout << "我正在运行..." << std::endl;sleep(1);int a = 10;a /= 0;}return 0;
}

运行结果如下:

可以看到进程收到了 Floating point exception。这个其实就是8号信号

可以自定义8号信号的行为来证明:

#include <iostream>
#include <string>#include <sys/types.h>
#include <signal.h>
#include <unistd.h>void catchSig(int signo)
{std::cout << "获取一个信号编号,编号是:" << signo << std::endl;
}int main()
{// 3.硬件异常产生信号// 信号产生,不一定由用户显示发送。有可能由操作系统自动产生signal(SIGFPE, catchSig);while (true){std::cout << "我正在运行..." << std::endl;sleep(1);int a = 10;a /= 0; // 为什么除0 会终止进程? 当前进程会收到来自OS的信号}return 0;
}

运行结果如下:

可以看到,该进程收到了8号信号。

可是为什么一直打印这条信息呢?我们没有写死循环

分析如下:

1 OS怎么知道该进程  \0 了?

        因为在cpu中有一个状态寄存器,这个寄存器中有一个状态标志位。如果我们有 \0 运算,就会导致结果溢出,此时这个寄存器就会将标志位由 0 设置为 1。说明该进程发生了运算异常。

        当OS发现某一个进程的状态标志位是1,就会向其发送8号信号终止它!

2 为什么会一直打印信息?

        一个进程不会一直占用CPU。当发送进程调度的时候,这个进程可能会被调走。此时进程会将自己的上下文信息保存到PCB中。当进程切换切换回来的时候,这个进程的状态标志位还是1,OS仍会向其发送8号信号,继续打印这条信息!

b 空指针解引用 

#include <iostream>
#include <string>#include <sys/types.h>
#include <signal.h>
#include <unistd.h>void catchSig(int signo)
{std::cout << "获取一个信号编号,编号是:" << signo << std::endl;
}int main()
{ signal(SIGFPE, catchSig);while (true){std::cout << "我正在执行代码" << std::endl;sleep(1);int *p = nullptr;*p = 1; //野指针}return 0;
}

运行结果如下:

 可以看到,显示段错误。收到11号信号(非法访问内存)

原因分析:

        我们的指针都是在虚拟内存上的,虚拟内存通过页表和MMU的映射到物理内存上(MMU是集成在CPU上的)。当我们发送非法访问的时候,MMU就会发送硬件异常,OS向进程发送11号信号进行终止。

        不断打印的原因如上面。

2.4 软件产生信号

a pipe 读端退出,写端立马退出

        在这篇文章中,我们看到。管道的读端退出,写端会收到13号信号退出

Linux操作系统4-进程间通信1(通信与管道实现通信)-CSDN博客

这就是一种软件异常产生的信号

b alarm定时器产生信号 

//头文件
#include <unistd.h>//函数原型
unsigned int alarm(unsigned int seconds);//使用alarm可以设定闹钟,在输入的参数 seconds 秒之后
//OS会向当前进程发送 SIGALRM 信号,该信号的默认行为是终止该进程

测试代码: 

#include <iostream>
#include <string>#include <sys/types.h>
#include <signal.h>
#include <unistd.h>void catchSig(int signo)
{std::cout << "获取一个信号编号,编号是:" << signo << std::endl;exit(1);
}int main()
{alarm(10);int count = 0;while (1){std::cout << "hello world! " << count++ << std::endl;sleep(1);}return 0;
}

运行结果: 

可以看到10秒后,进程收到14号信号退出 

        通过alarm定义闹钟我们可以写出很多有用的代码。

        任意一个进程都能通过alarm向OS中设置闹钟,OS会周期性检测这些闹钟,当闹钟到了之后OS就会向设置闹钟的进程发送信号。

        这种超时的行为,全部是由软件构成的。所以称为 软件条件产生信号

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

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

相关文章

如何在docker中的mysql容器内执行命令与执行SQL文件

通过 docker ps -a 查询当前运行的容器&#xff0c;找到想执行命令的容器名称。 docker ps -a若想执行sql文件&#xff0c;则将sql文件放入当前文件夹下后将项目内的 SQL 文件拷贝到 mysql 容器内部的 root下。 sudo docker cp /root/enterprise.sql mysql:/root/然后进入 my…

Git GitHub基础

git是什么&#xff1f; Git是一个分布式版本控制系统&#xff0c;用于管理源代码的变更。它允许多个开发者在同一个项目上协作&#xff0c;同时跟踪每个修改的历史记录。 关键词&#xff1a; 分布式版本控制软件 软件 安装到我们电脑上的一个工具 版本控制 例如论文&…

派可数据BI接入DeepSeek,开启智能数据分析新纪元

派可数据BI产品完成接入DeepSeek&#xff0c;此次接入标志着派可数据BI在智能数据分析领域迈出了重要一步&#xff0c;将为用户带来更智能、更高效、更便捷的数据分析体验。 派可数据BI作为国内领先的商业智能解决方案提供商&#xff0c;一直致力于为用户提供高效、稳定易扩展…

Linux-ftrace-双nop机制的实现

Linux 内核调试工具ftrace 之&#xff08;NOP动态插桩的实现原理&#xff09; ftrace 是 Linux 内核中的一种跟踪工具&#xff0c;主要用于性能分析、调试和内核代码的执行跟踪。它通过在内核代码的关键点插入探针&#xff08;probe&#xff09;来记录函数调用和执行信息。这对…

Qt互斥锁(QMutex)的使用、QMutexLocker的使用

Qt互斥锁【QMutex】的使用、QMutexLocker的使用 基于读写锁(QReadWriteLock)的线程同步Chapter1 Qt互斥锁(QMutex)的使用、QMutexLocker的使用一、QMutexLocker和QMutex实现示例图二、QMutex和QMutexLocker的关系&#xff08;个人理解&#xff09;三、QMutex使用和QMutexLocker…

SpringBoot ——简单开发流程实战

本文使用SpringBoot进行电商系统商品数据增删改查的简单开发流程。 本文目录 一、创建Spring Boot项目二、配置数据库连接三、创建实体类四、创建Repository接口五、创建Service层六、创建Controller层七、测试 一、创建Spring Boot项目 可以通过https://start.spring.io/或者…

fastadmin 后台商品sku(vue)

先上个效果图 首先先引入vue define([backend], function (Backend) {require.config({paths: {vue: /assets/jeekshopskugoods/libs/vue.min,skuimg: /assets/jeekshopskugoods/js/skuimg,skugoods: /assets/jeekshopskugoods/js/skugoods,layui: /assets/LayuiSpzj/layui/la…

C++蓝桥杯基础篇(六)

片头 嗨~小伙伴们&#xff0c;大家好&#xff01;今天我们来一起学习蓝桥杯基础篇&#xff08;六&#xff09;&#xff0c;练习相关的数组习题&#xff0c;准备好了吗&#xff1f;咱们开始咯&#xff01; 第1题 数组的左方区域 这道题&#xff0c;实质上是找规律&#xff0c;…

git -学习笔记

目录 基本操作语法 设置用户和邮箱 版本回退 工作区和暂存区 撤销修改 删除与恢复 一工作区删除了&#xff0c;但是暂存区没删除 二工作区误删了&#xff0c;暂存区还有 github-Git 连接 报错解决-push远程仓库被拒绝 远程库 分支 分支冲突 储藏分支 回到当前分…

Windows本地Docker+Open-WebUI部署DeepSeek

最近想在自己的电脑本地部署一下DeepSeek试试&#xff0c;由于不希望污染电脑的Windows环境&#xff0c;所以在wsl中安装了ollama&#xff0c;使用ollama拉取DeepSeek模型。然后在Windows中安装了Docker Desktop&#xff0c;在Docker中部署了Open-WebUI&#xff0c;最后再在Ope…

力扣785. 判断二分图

力扣785. 判断二分图 题目 题目解析及思路 题目要求将所有节点分成两部分&#xff0c;每条边的两个端点都必须在不同集合中 二分图&#xff1a;BFS/DFS/并查集 因为图不一定联通&#xff0c;所以枚举所有点都做bfs(如果没联通的话) 代码 class Solution { public:bool is…

springboot之集成Elasticsearch

目录 二、Elasticsearch 是什么&#xff1f;三、Elasticsearch 安装四、Springboot 集成 Elasticsearch 的方式五、创建项目集成 Elasticsearch 2.创建 Spring Initializr 项目 es &#xff08;3&#xff09;.新建实体类 User&#xff08;4&#xff09;.新建 dao 接口类 UserR…

[Lc滑动窗口_1] 长度最小的数组 | 无重复字符的最长子串 | 最大连续1的个数 III | 将 x 减到 0 的最小操作数

目录 1. 长度最小的字数组 题解 代码 ⭕2.无重复字符的最长子串 题解 代码 3.最大连续1的个数 III 题解 代码 4.将 x 减到 0 的最小操作数 题解 代码 1. 长度最小的字数组 题目链接&#xff1a;209.长度最小的字数组 题目分析: 给定一个含有 n 个 正整数 的数组…

数据集笔记:新加坡 地铁(MRT)和轻轨(LRT)票价

数据连接 data.gov.sg 2024 年 12 月 28 日起生效的新加坡地铁票价 该数据集包含 MRT 和 LRT 票价的信息&#xff0c;包括&#xff1a; 票价类型&#xff08;Fare Type&#xff09;&#xff1a;成人票、学生票、老年人票、残障人士票等。适用时间&#xff08;Applicable Tim…

【前端基础】Day 3 CSS-2

目录 1. Emmet语法 1.1 快速生成HTML结构语法 1.2 快速生成CSS样式语法 2. CSS的复合选择器 2.1 后代选择器 2.2 子选择器 2.3 并集选择器 2.4 伪类选择器 2.4.1 链接伪类选择器 2.4.2 focus伪类选择器 2.5 复合选择器总结 3. CSS的元素显示模式 3.1 什么是元素显示…

RabbitMQ操作实战

1.RabbitMQ安装 RabbitMQ Windows 安装、配置、使用 - 小白教程-腾讯云开发者社区-腾讯云下载erlang&#xff1a;http://www.erlang.org/downloads/https://cloud.tencent.com/developer/article/2192340 Windows 10安装RabbitMQ及延时消息插件rabbitmq_delayed_message_exch…

【北京迅为】itop-3568 开发板openharmony鸿蒙烧写及测试-第2章OpenHarmony v3.2-Beta4版本测试

瑞芯微RK3568芯片是一款定位中高端的通用型SOC&#xff0c;采用22nm制程工艺&#xff0c;搭载一颗四核Cortex-A55处理器和Mali G52 2EE 图形处理器。RK3568 支持4K 解码和 1080P 编码&#xff0c;支持SATA/PCIE/USB3.0 外围接口。RK3568内置独立NPU&#xff0c;可用于轻量级人工…

stm32hal库寻迹+蓝牙智能车(STM32F103C8T6)

简介: 这个小车的芯片是STM32F103C8T6&#xff0c;其他的芯片也可以照猫画虎,基本配置差不多,要注意的就是,管脚复用,管脚的特殊功能,(这点不用担心,hal库每个管脚的功能都会给你罗列,很方便的.)由于我做的比较简单,只是用到了几个简单外设.主要是由带霍尔编码器电机的车模,电机…

SQL命令详解之操作数据库

操作数据库 SQL是用于管理和操作关系型数据库的标准语言。数据库操作是SQL的核心功能之一&#xff0c;主要用于创建、修改和删除数据库对象&#xff0c;如数据库、表、视图和索引等。以下是SQL中常见的数据库操作命令及其功能简介&#xff1a; 1. 查询数据库 查询所有的数据库…

Go红队开发—编解码工具

文章目录 开启一个项目编解码工具开发Dongle包Base64编解码摩斯密码URL加解密AES加解密 MD5碰撞工具开发 开启一个项目 这作为补充内容&#xff0c;可忽略直接看下面的编解码&#xff1a; 一开始用就按照下面的步骤即可 1.创建一个文件夹&#xff0c;你自己定义名字(建议只用…