当前位置: 首页 > news >正文

Linux-进程信号

目录

  • 概念
  • 信号产生
  • 信号注册
  • 信号注销
  • 信号处理
    • 实例
  • 信号的基本应用

概念

进程信号:
概念:信号就是软件中断。信号就是用于向进程通知某个事件的产生,打断进程当前操作,去处理这个事件。
linux中信号的种类:使用kill -l命令查看所有信号–62种
1~31:非可靠信号(有可能会造成事件丢失)
34~64:可靠信号(不会丢失事件)
信号的生命周期:产生信号->在进程pcb中注册信号->注销信号->处理信号

信号产生

信号的产生
硬件产生
ctrl+c 退出进程
ctrl+| 退出进程
ctrl+z 暂停进程,此时ps -aux | grep 进程名称 可以看到进程处于停止状态。jobs:查看作业,通过fg 作业id:让停止作业继续运行
软件产生
kill命令发送信号给指定进程 kill -signum pid
kill命令杀死一个进程的原理:默认给进程发送了终止信号
int kill(pid_t pid, int sig); 给pid进程发送sig信号
int raise(int sig); – 给进程自身发送一个指定的信号
unsigned int alarm(unsigned int seconds);
–sec秒之后给进程自身发送一个时钟信号–SIGALRM
void abort(void); – 给进程自身发送一个SIGABRT信号
int sigqueue(pid_t pid, int sig, const union sigval value);
给一个进程发送信号的同时携带一个数据过去

信号注册

信号的注册
注册:在进程中注册一个信号让进程直到自己收到了某个信号
修改pending位图(用于标记是否收到了某个信号),添加一个信号信息节点
非可靠:如果信号没有被注册,则注册;否则什么都不做。链表中不会出现相同非可靠信号信息节点
可靠:不管信号是否注册,都会注册一下。链表中有可能又多个相同的信号信息节点。
sigqueue-双向链表 – 表示有多少信号

信号注销

信号的注销
注销:将信号信息进程pcb中一处(修改位图,删除节点)
非可靠:删除节点,修改位图为0
可靠:删除一个信号节点,检查链表中是否还有相同节点,没有则修改位图

信号处理

信号的处理
处理:信号的处理也叫信号的递达,实际上就是打断进程当前的操作,去执行进程的对应信号处理函数。
信号的处理方式:
1.默认处理方式
2.忽略处理方式
3.自定义处理方式–用户自己定义信号的处理回调函数
typedef void(*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
signum:信号值-表示要修改哪个信号的处理方式
handler:新的信号处理方式
SIG_DEL-默认;SIG_IGN-忽略;自定义函数的名称
返回值:成功则返回当前信号原来的处理方式

自定义处理方式的信号捕捉流程
信号是从程序运行从内核态返回用户态之前处理的。
程序处理信号时在内核态,当遇到回调函数自定义时,因为自定义函数是用户自己写的,返回用户态执行,完成后如果还有信号则继续返回内核态进行,当信号处理完成后返回用户态主流程。
程序运行可以通过中断,异常,系统调用从用户态运行切换到内核态

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>void sigcb(int signo)
{printf("recv signal:%d\n", signo);printf("时间到了\n");alarm(3);
}
int main(int argc, char *argv[])
{signal(信号,处理方式)signal(SIGALRM, sigcb);kill(进程ID,信号值)//kill(getpid(), SIGINT);//raise(SIGINT);alarm(3);while(1){printf("-----\n");sleep(1);}return 0;
}

阻塞:信号的阻塞–阻止信号被递达
一个信号被阻塞后,依然收到这个信号会注册,但是暂时不被处理
pcb中有pending位图-未决信号结合;还有阻塞信号集合
如果要阻塞一个信号,就是在进程的阻塞信号集合中标记这个信号
具体操作:
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
how:操作类型
SIG_BLOCK-- 阻塞set集合的信号 block = block | set
SIG_UNBLOCK – 将set集合中的信号解除阻塞 block &= ~set
SIG_SETMASK–将set集合中的信号设置为阻塞集合的信号block=set
返回值:成功返回0;失败返回-1

实例

先自定义特定信号的处理方式–做打印收到了哪个信号 signal
将所有信号阻塞 sigprocmask block
让程序运行停下来,在这期间给进程发送信号getchar
解除这些信号的阻塞,查看信号处理结果 sigprocmask unblock

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>void sigcb(int signo)
{printf("recv signal:%d\n", signo);
}
int main(int argc, char *argv[])
{signal(SIGINT, sigcb);signal(40, sigcb);sigset_t set;sigemptyset(&set);sigfillset(&set);//zu sesigprocmask(SIG_BLOCK, &set, NULL);printf("回车后,继续运行\n");getchar();printf("解除信号阻塞,查看结果\n");sigprocmask(SIG_UNBLOCK, &set, NULL);while(1){sleep(1);}return 0;
}

通过实例,按三次ctrl c,输入四次kill -40命令。最终结果显示ctrl c一次,kill -40四次。
因为ctrl c是SIGINT,在前31属于不可靠信号,因此同时发送阻塞只保留一个。kill -40属于可靠信号,每次发送都保留,等阻塞结束后依次回调。

两个比较特殊的信号:SIGKILL/SIGSTOP 这两个信号不可被阻塞,不可被自定义,不可被忽略,说白了就是无法修改处理方式。

信号的基本应用

信号的基本应用:
SIGCHLD信号:一个子进程退出后,给父进程发送的子进程状态改变信号
但是SIGCHLD默认处理方式就是什么都不做
要避免僵尸进程,则需要在父进程中wait阻塞等待。
如果不想阻塞等待,则可以使用信号来解决
自定义SIGCHLD信号的处理方式,在回调函数中调用waitpid接口
SIGCHLD是一个非可靠信号–意味着多个子进程同时退出,有可能丢失事件
signal(SIGCHLD,SIG_IGN);–显式忽略

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>
#include<sys/wait.h>void sigcb(int no)
{printf("son fork exit\n");waitpid(-1, NULL, 0);
}
int main(int argc, char *argv[])
{signal(SIGCHLD, sigcb);pid_t pid = fork();if(pid == 0){ sleep(3);exit(0);}while(1){printf("------\n");sleep(1);}return 0;
}

waitpid();有子进程退出返回值>0;没有子进程退出返回值==0;出错<0
wait(-1, NULL, WNOHANG)
-1:等待任意一个子进程的退出
NULL:返回值不关心
WNOHANG:将接口设置为非阻塞

SIGPIPE:管道所有读端被关闭则write出发异常对应的信号
SIGPIPE信号默认处理方式就是退出进程,若不想退出则需要自定义/忽略

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<errno.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<string.h>
#include<signal.h>void sigcb(int no)
{printf("all pipe read is close\n");
}
int main(int argc, char *argv[])
{
//更换信号处理方式signal(SIGPIPE, sigcb);umask(0);char *fifo_name = "./test.fifo";int ret = mkfifo(fifo_name, 0664);if(ret < 0 && errno != EEXIST){perror("mkfifo error");return -1;}int fd = open(fifo_name, O_WRONLY);if(fd < 0){perror("open error");return -1;}while(1){char buf[1024] = {0};scanf("%s", buf);int ret = write(fd, buf, strlen(buf));if(ret < 0){perror("write error");return -1;}}close(fd);return 0;
}

关键字:volatile
功能:保持内存可见性–让cpu每次访问变量的时候都从内存中重新获取数据
目的:防止编译器过度优化

可重入函数与不可重入函数:
函数的重入:在不同的执行流程中(main、signal)同时进入一个函数进行执行。
不可重入:一个函数重入后,有可能会造成数据二义或者逻辑混乱。
可重入:一个函数重入后,不会出现问题。
函数是否可重入的重点:一个函数中是否对全局数据进行不受保护的非原子操作(是-不可重入)

//不可重入
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>int a = 0, b = 0;int test()
{a++;sleeo(1);b++;printf("%d + %d = %d\n",a, b, a+b);
}void sigcb(int no)
{test();
}int main(int argc, char *argv[])
{signal(SIGINT, sigcb);test();return 0;
}

相关文章:

Linux-进程信号

目录 概念信号产生信号注册信号注销信号处理实例 信号的基本应用 概念 进程信号&#xff1a; 概念&#xff1a;信号就是软件中断。信号就是用于向进程通知某个事件的产生&#xff0c;打断进程当前操作&#xff0c;去处理这个事件。 linux中信号的种类&#xff1a;使用kill -l命…...

Linux服务器安装jdk

背景: 安装JDK是我们java程序在服务器运行的必要条件,下面描述几个简单的命令就可再服务器上成功安装jdk 命令总览: yum update -y yum list | grep jdk yum -y install java-1.8.0-openjdk java -version 1.查看可安装版本 yum list | grep jdk 2.如果查不到可先进行 yum upd…...

基于 HBase Phoenix 构建实时数仓(2)—— HBase 完全分布式安装

目录 一、开启 HDFS 机柜感知 1. 增加 core-site.xml 配置项 2. 创建机柜感知脚本 3. 创建机柜配置信息文件 4. 分发相关文件到其它节点 5. 重启 HDFS 使机柜感知生效 二、主机规划 三、安装配置 HBase 完全分布式集群 1. 在所有节点上配置环境变量 2. 解压、配置环境…...

equals()与==的区别

在Java中 可以对基本类型进行比较,比较的是值是否相等 也可以对引用类型(对象)进行比较,比较的是引用变量所指向的空间地址 public static void main(String[] args) {int a 10;int b 10;System.out.println(ab);//true// 基本类型比较,比较值是否相等String s1 new Stri…...

什么是数据采集与监视控制系统(SCADA)?

SCADA数据采集是一种用于监控和控制工业过程的系统。它可以实时从现场设备获得数据并将其传输到中央计算机&#xff0c;以便进行监控和控制。SCADA数据采集系统通常使用传感器、仪表和控制器收集各种类型的数据&#xff0c;例如温度、压力、流量等&#xff0c;然后将这些数据汇…...

基于SpringBoot+Vue+ElementUI+Mybatis前后端分离管理系统超详细教程(五)——多条件搜索并分页展示

前后端数据交互 书接上文&#xff0c;我们上节课通过前后端数据交互实现了分页查询和单条件搜索分页查询的功能&#xff0c;最后留了个小尾巴&#xff0c;就是把其他两个搜索条件&#xff08;email,address&#xff09;也加进来&#xff0c;实现多条件搜索并分页展示。这节课我…...

鸿蒙实战开发Camera组件:【相机】

相机组件支持相机业务的开发&#xff0c;开发者可以通过已开放的接口实现相机硬件的访问、操作和新功能开发&#xff0c;最常见的操作如&#xff1a;预览、拍照和录像等。 基本概念 拍照 此功能用于拍摄采集照片。 预览 此功能用于在开启相机后&#xff0c;在缓冲区内重复采集…...

政安晨:【深度学习处理实践】(三)—— 处理时间序列的数据准备

在深度学习中&#xff0c;对时间序列的处理主要涉及到以下几个方面&#xff1a; 序列建模&#xff1a;深度学习可以用于对时间序列进行建模。常用的模型包括循环神经网络&#xff08;Recurrent Neural Networks, RNN&#xff09;和长短期记忆网络&#xff08;Long Short-Term M…...

PCL不同格式点云读取速度(Binary和ASCII )

首先说明一点&#xff1a;Binary(二进制)格式点云文件进行读取时要比Ascll码格式点云读取时要快的多&#xff0c;尤其是对于大型的点云文件&#xff0c;如几百万、甚至几千万个点云的情况下。 今天遇到了一种情况&#xff0c;在写项目的时候进行点云读取&#xff0c;读取的时候…...

Neo4J图数据库入门示例

前言 - Neo4j和MySQL的区别 Neo4j 和 MySQL 是两种不同类型的数据库&#xff0c;它们在数据模型、用途、性能和查询语言等方面有着显著的区别。以下是它们的主要区别&#xff1a; 数据模型&#xff1a; Neo4j 是一种图数据库&#xff0c;它使用图数据模型来存储和查询数据。在…...

牛客每日一题之 二维前缀和

题目介绍&#xff1a; 题目链接&#xff1a;【模板】二维前缀和_牛客题霸_牛客网 先举两个简单的例子&#xff0c;来帮大家理解题目&#xff0c;注意理解二维前缀和要先要一维前缀和的基础&#xff0c;不了解的可以看我上一篇博客。 若x11&#xff0c;y11, x23, y2 3,这是要…...

动态规划 Leetcode 70 爬楼梯

爬楼梯 Leetcode 70 学习记录自代码随想录 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 示例 1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;2 解释&#xff1a;有两种方法可以爬到…...

(未解决)macOS matplotlib 中文是方框

reference&#xff1a; Mac OS系统下实现python matplotlib包绘图显示中文(亲测有效)_mac plt 中文值-CSDN博客 module ‘matplotlib.font_manager‘ has no attribute ‘_rebuild‘解决方法_font_manager未解析-CSDN博客 # 问题描述&#xff08;笑死 显而易见 # solve 找到…...

深入探讨C#中的递归算法

一、什么是递归算法&#xff1f; 递归是指一个函数或方法在执行过程中调用自身的情况。递归算法是编程中常见的一种解决问题的方法。它将一个问题分解成一个或多个与原问题相似但规模更小的子问题&#xff0c;然后通过解决这些子问题来解决原问题。递归算法通常用于解决重复性的…...

三款顶级开源RAG (检索增强生成)工具:Verba、Unstructured 和 Neum

三款顶级开源RAG (检索增强生成)工具&#xff1a;Verba、Unstructured 和 Neum 概述 随着企业对话式数据处理需求的提升&#xff0c;面临的挑战是数据隐私性和缺乏企业级解决方案。虽然类似LangChain能在短时间内构建RAG应用&#xff0c;但忽视了文档解析、多来源数据ETL、批量…...

VC++、MFC中操作excel时,CRange中get_EntireRow()和get_EntireColumn()函数的用法及区别是什么?

在VC和MFC中操作Excel时&#xff0c;通过COM接口与Excel交互时&#xff0c;CRange 对象&#xff08;或更准确地说是 Excel::Range 对象&#xff09;代表一个单元格范围。CRange 类提供了一系列方法来获取或操作这个范围内的单元格。其中&#xff0c;get_EntireRow() 和 get_Ent…...

npm 操作报错记录1- uninstall 卸载失效

npm 操作报错记录1- uninstall 卸载失效 1、问题描述 安装了包 vue/cli-plugin-eslint4.5.0 vue/eslint-config-prettier9.0.0 但是没有使用 -d &#xff0c;所以想重新安装&#xff0c;就使用 uninstall 命令卸载&#xff0c;结果卸载了没反应&#xff0c;也没有报错&#xf…...

openCV保存图像

保存图像 //保存为png透明通道vector<int>opts;opts.push_back(IMWRITE_PAM_FORMAT_RGB_ALPHA);imwrite("D:/img_bgra.png", img, opts);//保存为单通道灰度图像img cv::imread(imagePath.toStdString(), IMREAD_GRAYSCALE);vector<int> opts_gray;opts…...

mac 配置.bash_profile不生效问题

1、问题描述 mac系统中配置了环境变量只能在当前终端生效&#xff0c;切换了终端就无效了&#xff0c;查了下问题所在。mac系统会预装一个终极shell - zsh&#xff0c;环境变量读取在 .zshrc 文件下。 2、解决方案 1、切换终端到bash 切换终端到bash chsh -s /bin/bash 切换终端…...

【Cesium for Supermap】S3MTiles图层box裁剪

效果图&#xff1a; 代码&#xff1a; let viewer new Cesium.Viewer(cesiumContainer);// 添加SuperMap iServer发布的S3M缓存服务let promise viewer.scene.addS3MTilesLayerByScp("http://www.supermapol.com/realspace/services/3D-BIMbuilding/rest/realspace/data…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开&#xff0c;首…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...

绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化

iOS 应用的发布流程一直是开发链路中最“苹果味”的环节&#xff1a;强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说&#xff0c;这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发&#xff08;例如 Flutter、React Na…...

前端工具库lodash与lodash-es区别详解

lodash 和 lodash-es 是同一工具库的两个不同版本&#xff0c;核心功能完全一致&#xff0c;主要区别在于模块化格式和优化方式&#xff0c;适合不同的开发环境。以下是详细对比&#xff1a; 1. 模块化格式 lodash 使用 CommonJS 模块格式&#xff08;require/module.exports&a…...