【Linux】IPC-信号

在这里插入图片描述

💻文章目录

  • 📄前言
  • 信号
    • 概念
    • 信号阻塞
      • 概念
    • 信号的处理
    • 信号的使用
  • 📓总结


📄前言

信号,一种无论是生活还是编程都离不开的东西。生活中,我们通过信号来对外部发生的事情进行反应,就好像你的手机来了一条信息,你可以选择点开处理它,也可以忽略掉它,而在Linux中的信号也是如此。

信号

概念

信号是Linux进程间通信的一种方式,主要用于进程接受异步事件的通知。你可以把信号看出是一种软件中断(软件触发的中断机制),进程通过接受信号来对响应外部的事情,例如程序异常、子进程结束、终端中按下中断键(Ctrl + C)都是会给进程传递信号。

Linux中信号分为两类: 标准信号与实时信号。

  • 标准信号:linux中的1-32号信号都是标准信号,信号被处理前,只能被存储一次。

  • 实时信号:指的是34号信号以上的信号,他们比标准信号更高级,可以使用队列来存储。

╭─ ~/.lcpr                                                           
╰─❯ kill -l	# 使用kill -l 来查看所有信号
HUP INT QUIT ILL TRAP IOT BUS FPE KILL USR1 SEGV USR2 PIPE ALRM TERM STKFLT CHLD CONT STOP TSTP TTIN TTOU URG XCPU XFSZ VTALRM PROF WINCH POLL PWR SYS# 如果我们想要对某个进程发送信号,也是使用kill
kill 【you_process】 【signal】;# 当然,我们也有更简易的发送信号的方式
# 使用键盘(Ctrl + C)发送 INT 信号
# 使用(Ctrl + Z) 发送 STOP 信号
# 使用 (Ctrl + \)发送

信号阻塞

概念

当我们程序正在执行某些重要任务的时候,可以会因为用户的任性(Ctrl + C)而随意传来SIGINT信号来结束进程,为了不让程序收到这种事情的影响,linux信号机制设计了两个关键的标志位:阻塞位与未决位(2bit)。

信号工作原理:

  • 信号到达且阻塞位为0,系统则将未决位设为1,并执行信号处理函数,处理完成将未决位重新设置位0
  • 信号到达阻塞位为1,系统则将未决位设为1,信号处理等待状态,直到阻塞被取消,信号被处理。
+---------------------+
|      task_struct    |
+----------+----------+----------------------+
| Signal   | Block    | Pending  | Handler   |
+----------+----------+----------+-----------+
| SIGHUP   |    0     |    0     | SIG_DFL   |
| SIGINT   |    1     |    1     | SIG_IGN   |
| SIGQUIT  |    1     |    0     | handler   | --*
|   ...    |   ...    |   ...    |   ...     |   |
+----------+----------+----------+-----------+   ||*----------------------*|vvoid sighandler(int signo) {...}

信号阻塞函数的介绍:

// 涉及头文件 <signal.h>struct sigset_t;	// 信号的集合,用于阻塞、等待、检查信号int sigemptyset(sigset_t *set);	//置空set
int sigfillset(sigset_t *set);	//初始化set,将所有信号添加到set中int sigaddset(sigset_t *set, int signum);	//为set增加信号
int sigdelset(sigset_t *set, int signum);	//删除set中的信号int sigismember(const sigset_t *set, int signum);
// 检查set中是否加入了signumint sigprocmask(int how, const sigset_t* set, sigset_t* oset);	//用于设置堵塞信号
// HOW 有三种参数,SIG_BLOCK、SIG_UNBLOCK、SIG_SETMASK// SIG_BLOCK:将set指向的信号集中的信号添加到当前阻塞信号集中// SIG_UNBLOCK:从当前阻塞信号集中移除set指向的信号集中的信号// SIG_SETMASK:将当前阻塞信号集设置为set指向的信号集的确切副本int sigpending(sigset_t* set);	
//用于检查当前进程哪些信号是阻塞未处理的,set用于储存这些信号。

阻塞信号函数的简单使用:

void task()
{pid_t id = getpid();for (int i = 1; i <= 32; ++i){if (i == SIGSTOP && i == SIGKILL)	//SIGSTOP 和 SIGKILL 无法被阻塞。continue;kill(id, i);printf("kill %d %d\n", id, i);sleep(1);}exit(0);
}void test()
{sigset_t set;// sigemptyset(&set);	//将set信号集设为空// for (int i = 1; i <= 32; ++i)		//     sigaddset(&set, i);	// 一个个添加信号sigfillset(&set);		// 初始化:将所有信号填加sigprocmask(SIG_SETMASK, &set, nullptr);	// 将set中的信号全部设为阻塞pid_t id = fork();	if (id == 0)task();wait(nullptr);
}

信号的处理

信号的处理方式有三种:默认处理、忽略信号或捕捉信号(自定义处理)。大部分信号的默认成立方式都是终止进程,但程序可以通过捕获信号(自定义信号处理函数)。除此之外,我们也可以将信号设为阻塞状态,这样程序就无法接受到信号。

    +-----------+       +-----------+       +-------------+|           |       |           |       |             ||  Kernel   |  ---> |  Process  |  ---> |  Signal     || (System)  |       |           |       |  Handler    |+-----------+       +-----------+       +-------------+^  |                  |                    ||  |                  |                    ||  +---- 发送信号 ----->             自定义的处理函数|                                          |+------- 产生信号(如:Ctrl+C, 异常)---------+

在C语言中,可以使用 signal 函数与 sigaction 函数来设置处理函数。

信号处理函数的介绍:

void(*signal(int sig, void(*func)(int)))(int);
// 看到这个这个函数原型你可能会面露难色。 但其实在里面我们只需要认识两个参数就足够了。
// sig:需要捕获的信号     func:一个函数指针,指向你自定义的捕获函数。
// 而signal的返回值也是和func一个类型的函数指针int sigaction(int sig, const struct sigaction* act, struct sigaction* oldact);
// sig:需要处理的信号   
// act:指向对信号的处理方式
// oldact:用于保存信号先前的处理方式,可设为NULL// struct sigaction的结构
struct sigaction {void     (*sa_handler)(int);	//信号处理函数指针void     (*sa_sigaction)(int, siginfo_t *, void *);	// 另一个处理信号的函数,当sa_flags 设置了”SA_SIGINFO“的时候使用。sigset_t   sa_mask;	//在信号处理函数执行时,额外需要阻塞的信号int        sa_flags;	// 用于指定信号处理的各种选项与行为void     (*sa_restorer)(void);	// 通常不使用
};

信号的使用

void task()
{struct sigaction act;sigset_t set;sigemptyset(&set);	//将set设空sigfillset(&act.sa_mask);	//初始化sigprocmask(SIG_SETMASK, &act.sa_mask, nullptr);	//sa_mask信号集阻塞for (int i = 1; i <= 32; ++i){if (i == SIGSTOP || i == SIGKILL)continue;raise(i);	//使用raise来向本进程发送信号}sigpending(&set);for (int i = 32; i > 0; --i){if (sigismember(&set, i) == 0)	//检查信号是否未决std::cout << i << std::endl;}std::cout << std::endl;
}int main()
{signal(SIGCHLD, SIG_IGN);	//子进程结束时发送SIGCHLD信号,将它设为SIG_IGN可免除waitpid_t id = fork();if (id == 0){task();return 0;}return 0;
}

📓总结

本篇文章我们探索从信号的概念到阻塞和处理函数的应用,相信你对linux系统编程又有了一个新的了解吧。

📜博客主页:主页
📫我的专栏:C++
📱我的github:github

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

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

相关文章

Vue.js+SpringBoot开发个人健康管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 健康档案模块2.2 体检档案模块2.3 健康咨询模块 三、系统展示四、核心代码4.1 查询健康档案4.2 新增健康档案4.3 查询体检档案4.4 新增体检档案4.5 新增健康咨询 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpri…

程序员必备开发工具、程序员必备集成开发环境(IDE)

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

CTP-API开发系列之十:v6.7.0-Python版封装(Windows/Linux)(附源码)

CTP-API开发系列之十&#xff1a;v6.7.0-Python版封装&#xff08;Windows/Linux&#xff09;&#xff08;附源码&#xff09; CTP-API开发系列之十&#xff1a;v6.7.0-Python版封装&#xff08;Windows/Linux&#xff09;&#xff08;附源码&#xff09;资源获取准备工作Windo…

2023年全球软件质量效能大会(QECon上海站):智慧碰撞,质量与效能的新篇章(附大会核心PPT资料下载)

在数字化浪潮席卷全球的今天&#xff0c;软件行业正以前所未有的速度发展。作为推动这一进程的重要力量&#xff0c;软件质量与效能的提升显得尤为关键。2023年全球软件质量&效能大会&#xff08;QECon上海站&#xff09;的盛大召开&#xff0c;无疑为业界提供了一次难得的…

【b站咸虾米】2 Vue基础(上) 2021最新Vue从基础到实例高级_vue2_vuecli脚手架博客案例

课程地址&#xff1a;【2021最新Vue从基础到实例高级_vue2_vuecli脚手架博客案例】 https://www.bilibili.com/video/BV1pz4y1S7bC/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 目录 2 Vue基础 上 2.0 补充知识 2.0.1 Vue实例的作用范围 2.0.2 t…

50、东北大学、阿尔伯塔大学:Hi-GCN从2个层次角度进行图学习,用来诊断脑部疾病[你这和MVS-GCN套娃呢?]

本文由东北大学医学图像智能计算教育部重点实验室&#xff0c;加拿大阿尔伯塔大学于2020年10.24日发表于<Computers in Biology and Medicine> JCR\IF: Q1\7.7 Abstract&#xff1a; 目的:近年来&#xff0c;脑连接网络已被用于神经系统疾病的分类&#xff0c;如自闭症…

489: 平方和与立方和

收藏 难度&#xff1a;简单 标签&#xff1a;暂无标签 题目描述 给定一段连续的整数&#xff0c;求出他们中所有偶数的平方和以及所有奇数的立方和。 输入 输入数据包含多组测试实例&#xff0c;每组测试实例包含一行&#xff0c;由两个整数m和n组成。(m ,n不相等) m,n为要…

【论文翻译】UP-DETR—Unsupervised Pre-training for Detection Transformers

0.论文摘要 摘要——通过Transformer model编码器——解码器架构&#xff0c;用于目标检测的检测Transformer model&#xff08;DETR&#xff09;达到了与Faster R-CNN相比具有竞争力的性能。然而&#xff0c;使用scratch transformers训练&#xff0c;DETR需要大规模的训练数…

【docker】docker的常用命令

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;中间件 ⛺️稳中求进&#xff0c;晒太阳 常规命令 docker version #查看docker 版本信息docker info #显示docker 的系统信息&#xff0c;包括镜像和容器数量docker --help #查看所有的命…

如何发布新闻稿?如何让媒体记者报道自己的企业?

目前&#xff0c;很多企业和个人创业者都知道用新闻稿或软文来做宣传&#xff0c;但是一般只可以发布到自己的微信公众号、百家号等自媒体平台&#xff0c;往往收效甚微。有企业找到小马识途营销顾问咨询原因&#xff0c;小马识途营销顾问分析自媒体上发软文效果不明显的原因主…

【超图】SuperMap如何使知识图谱与BIM数据的绑定

作者&#xff1a;taco 近两年知识图谱的概念突然大火了起来&#xff0c;随之而来的就是用户的各种需求&#xff0c;你们的知识图谱能干什么呢&#xff1f;知识图谱有哪些应用呢&#xff1f;在结合客户的一些需求&#xff0c;以及自身的一些想法&#xff0c;写下这篇文章。 一、…

Day10|栈与队列part01:232.用栈实现队列、225.用队列实现栈

232. 用栈实现队列 使用两个栈&#xff0c;注意pop和peek&#xff1a; class MyQueue {private Stack<Integer> stackIn;private Stack<Integer> stackOut;public MyQueue() {stackIn new Stack<>();stackOut new Stack<>();}public void push(int…

【前端框架的发展史详细介绍】

前端框架的发展史 前端框架的发展史可以追溯到1995年&#xff0c;当时微软推出了IE浏览器并开始支持CSS&#xff0c;随后&#xff0c;在1997年&#xff0c;W3C&#xff08;万维网联盟&#xff09;发布了CSS的第一个正式标准。 在2003年&#xff0c;苹果推出了Safari浏览器&am…

MySQL的insert-on-duplicate语句详解

一、insert-on-duplicate语句语法 注意&#xff1a;ON DUPLICATE KEY UPDATE只是 MySQL的特有语法&#xff0c;并不是SQL标准语法&#xff01; INSERT INTO … ON DUPLICATE KEY UPDATE 是 MySQL 中一种用于插入数据并处理重复键冲突的语法。 这个语法适用于在 insert的时候…

抖音直播招聘的主要优势有哪些?

触达广泛受众抖音拥有海量活跃用户,通过直播可以瞬间吸引大量观众关注。相比传统招聘渠道,抖音直播能够触达到更广泛、更多样化的人才群体。 提升品牌形象在直播中,企业可以展现自身独特的企业文化和价值观,增强与观众的互动交流,有助于提升品牌形象和美誉度。 精准招聘定位企业…

Java项目:53 springboot校园管理系统的设计与实现014

作者主页&#xff1a;舒克日记 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 1、关于校园管理系统的基本要求&#xff1a; &#xff08;1&#xff09;功能要求&#xff1a;可以管理首页、个人中心、院校管理、用户管理、单位类别…

30天拿下Rust之Trait

概述 在Rust中&#xff0c;Trait是一个核心概念&#xff0c;它允许我们定义类型应该具有的行为。Trait类似于其他语言中的接口&#xff0c;但Rust的Trait更为强大和灵活。它不仅定义了一组方法&#xff0c;还允许我们指定方法的默认实现、泛型约束和继承。通过Trait&#xff0c…

Spirngboot中文乱码解决方案

在使用springboot的时候,如果我们直接在控制器里面返回中文, 则默认可能会是乱码,因为默认的编码是ISO8859-1, 要解决这个问题, 就需要我们通过重写springboot里面的configureMessageConverters方法来将默认的编码设置为utf-8即可解决, 当然你的类文件编码也必须要是utf-8的, …

leetcode-打家劫舍专题系列(动态规划)

198.打家劫舍 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。 给定一个代表每个…

724.寻找数组的中心下标

题目&#xff1a;给你一个整数数组 nums &#xff0c;请计算数组的 中心下标 。 数组 中心下标 是数组的一个下标&#xff0c;其左侧所有元素相加的和等于右侧所有元素相加的和。 如果中心下标位于数组最左端&#xff0c;那么左侧数之和视为 0 &#xff0c;因为在下标的左侧不…