【Linux学习】进程间通信 (2) —— 信号

下面是有关进程通信中信号的相关介绍,希望对你有所帮助!

小海编程心语录-CSDN博客

目录

1. 信号 

1.1 概念 

1.2 信号的产生 

1.3 信号的处理方式 

2. 函数 

2.1 kill() 函数 

2.2 signal()函数 

2.3 sigaction()函数 

2.4 sigprocmask()函数 

2.5 sigqueue()函数 


1. 信号 

1.1 概念 

信号是进程间通信 UNIX IPC 中的其中一种通信方式,信号是事件发生时对进程的通知机制,也可以把它称为软件中断。大多数情况下,是无法预测信号达到的准确时间,所以,信号提供了一种处理异步事件的方法—— kill 命令查看所有信号。

ps -aux 指令可以看执行语句的pid等信息

1.2 信号的产生 

目的信号的目的是用来通信,当发生某种情况 下,通过信号将情况“告知”相应的进程,从而达到同步、通信的目的

信号由谁发出:

  1. 硬件发生异常,即硬件检测到错误条件并通知内核,随即再由内核发送相应的信号给相关进程。(异常包括执行一条异常的机器语言指令,诸如,除数为 0、数组访问越界导致引用了无法访问的内存区域等,这些异常情况都会被硬件检测到)
  2. 用于在终端下输入了能够产生信号的特殊字符。 譬如在终端上按下 CTRL + C 组合按键可以产生中断信号(SIGINT),通过这个方法可以终止在前台运行的进程
  3. 进程调用 kill()系统调用可将任意信号发送给另一个进程
  4. 用户可以通过 kill 命令将信号发送给其它进程,譬如在终端下执行"kill -9 xxx"来杀死 PID 为 xxx 的进程。 kill 命令其内部的实现原理便是通过 kill()系统调用来完成的。
  5. 发生了软件事件,即当检测到某种软件条件已经发生。(进程所设置的定时器 已经超时、进程执行的 CPU 时间超限、进程的某个子进程退出等等)

1.3 信号的处理方式 

当进程接收到内核或用户发送过来的信号之后,根据具体信号可以采取不同的处理方式:忽略信号、捕获信号或者执行系统默认操作。 Linux 系统提供了系统调用signal()和 sigaction()两个函数用于设置信号的处理方式

  1. 忽略信号:当信号到达进程后,该进程并不会去理会它、直接忽略,就好像是没有出现该 信号,信号对该进程不会产生任何影响。事实上,大多数信号都可以使用这种方式进行处理,但有 两种信号却决不能被忽略,它们是 SIGKILL 和SIGSTOP,因为它们 向内核和超级用户提供了使进程终止或停止的可靠方法
  2. 捕获信号:当信号到达进程后,执行预先绑定好的信号处理函数。Linux 系统提供了 signal()系统调用可用于注册信号的处理函数
  3. 执行系统默认操作:进程不对该信号事件作出处理,而是交由系统进行处理,每一种信号都会有其 对应的系统默认的处理方式,对大多数信号来说,系 统默认的处理方式就是终止该进程

 

2. 函数 

2.1 kill() 函数 

//函数原型
#include <sys/types.h>
#include <signal.h>int kill(pid_t pid, int sig);//pid:接收信号的进程PID,称为目标进程
//sig:信号的编号

2.2 signal()函数 

//函数原型
#include <signal.h>typedef void (*sig_t)(int);
sig_t signal(int signum, sig_t handler);/*
signum: 此参数指定需要进行设置的信号,可使用信号名或信号的数字编号handler: sig_t 类型的函数指针,指定要关联的响应函数,也可以设 置为 SIG_IGN 或 SIG_DFL, SIG_IGN 表示此进程需要忽略该信号, SIG_DFL 则表示设置为系统默认操作返回值: 此函数的返回值也是一个 sig_t 类型的函数指针,成功情况下的返回值则是指向在此之前的信 号处理函数;如果出错则返回 SIG_ERR,并会设置 errno。
*/

signal()函数是 Linux 系统下设置信号处理方式最简单的接口, 可将信号的 处理方式设置为捕获信号、 忽略信号以及系统默认操作

示例代码 

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>typedef void (*sig_t)(int);
sig_t signal(int signum, sig_t handler);void sig_handler(int sig)
{printf("Received signal: %d\n", sig);
}int main(int argc, char *argv[])
{sig_t ret = NULL;ret = signal(SIGINT, sig_handler);if (SIG_ERR == ret){perror("signal error");exit(-1);}while(1){}exit(0);
}

2.3 sigaction()函数 

//函数原型
#include <signal.h>
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
/*
signum: 需要设置的信号,除了 SIGKILL 信号和 SIGSTOP 信号之外的任何信号。
act: act 参数是一个 struct sigaction 类型指针,指向一个 struct sigaction 数据结构,该数据结构描述了信
号的处理方式,如果参数 act 不为 NULL,则表示需要为信号设置新的处理方式;如
果参数 act 为 NULL,则表示无需改变信号当前的处理方式。
oldact: oldact 参数也是一个 struct sigaction 类型指针,指向一个 struct sigaction 数据结构。如果参数
oldact 不为 NULL, 则会将信号之前的处理方式等信息通过参数 oldact 返回出来;如果无意获取此类信息,
那么可将该参数设置为 NULL。
返回值: 成功返回 0;失败将返回-1,并设置 errno
*/

除了signal()之外, sigaction()系统调用是设置信号处理方式的另一选择,虽然sigaction()更为复杂,但 sigaction()更具灵活性以及移植性。

sigaction()允许单独获取信号的处理函数而不是设置,并且还可以设置各种属性对调用信号处理函数时 的行为施以更加精准的控制

2.4 sigprocmask()函数 

 内核为每一个进程维护了一个信号掩码,当进程接收到一个属于 信号掩码中定义的信号时,该信号将会被阻塞、无法传递给进程进行处理。

//函数原型
#include <signal.h>
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);

函数参数和返回值含义如下:

  1. how: 参数 how 指定了调用函数时的一些行为。
  2. set: 将参数 set 指向的信号集内的所有信号添加到信号掩码中或者从信号掩码中移除;如果参数 set 为 NULL,则表示无需对当前信号掩码作出改动。
  3. oldset: 如果参数 oldset 不为 NULL,在向信号掩码中添加新的信号之前,获取到进程当前的信号掩码, 存放在 oldset 所指定的信号集中;如果为 NULL 则表示不获取当前的信号掩码
  4. 返回值: 成功返回 0;失败将返回-1,并设置 errno

示例代码 

实现对SIGINT信号的屏蔽

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>static void sig_handler(int sig)
{printf("Received signal: %d\n", sig);
}
int main(void)
{struct sigaction sig = {0};sigset_t sig_set;// 注册信号处理函数 sig.sa_handler = sig_handler;sig.sa_flags = 0;if (-1 == sigaction(SIGINT, &sig, NULL))exit(-1);// 信号集初始化 sigemptyset(&sig_set);//添加SIGINT信号sigaddset(&sig_set, SIGINT);// 向信号掩码中添加信号 if (-1 == sigprocmask(SIG_BLOCK, &sig_set, NULL))exit(-1);printf("正在休眠,此时对SIGINT信号屏蔽\n");sleep(5);printf("休眠结束\n");// 从信号掩码中移除添加的信号 if (-1 == sigprocmask(SIG_UNBLOCK, &sig_set, NULL))exit(-1);while(1){}exit(0);
}

2.5 sigqueue()函数 

该函数的功能与kill一样,都是向指定进程发送信号,但sigqueue在发送信号的同时会携带很多额外信息。

//函数原型
#include <signal.h>int sigqueue(pid_t pid, int sig, const union sigval value);

函数参数和返回值含义如下:

  1. pid: 指定接收信号的进程对应的 pid,将信号发送给该进程
  2. sig: 指定需要发送的信号
  3. value: 参数 value 指定了信号的伴随数据, union sigval 数据类型
  4. 返回值: 成功将返回 0;失败将返回-1,并设置 errno

如果喜欢请不吝给予三连支持!

小海编程心语录-CSDN博客

 

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

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

相关文章

文盘Rust -- 生命周期问题引发的 static hashmap 锁

100编程书屋_孔夫子旧书网 2021年上半年,撸了个rust cli开发的框架,基本上把交互模式,子命令提示这些cli该有的常用功能做进去了。项目地址:https://github.com/jiashiwen/interactcli-rs。 春节以前看到axum已经0.4.x了,于是想看看能不能用rust做个服务端的框架。 春节…

如何从Android恢复已删除的文件?3 种有效的方式

有时我们可能会错误地删除Android设备上的重要文件。更疯狂的是&#xff0c;Android手机上的文件在一夜之间消失了&#xff0c;我们不知道为什么。我们感到非常遗憾和恼火&#xff0c;但不知道。但是&#xff0c;此时学习如何从Android手机恢复已删除的文件为时已晚&#xff0c…

Excel 取出每组最后一行

Excel的前两列是两层的分组列&#xff0c;后两列是明细 ABCD1CM11112CM12123CM13134CM14145CM25156CM26167BM11218BM12229BM232310AM113111AM323212AM333313AM3434 现在要取出每小组的最后一行&#xff1a; ABCD1CM14142CM26163BM12224BM23235AM11316AM3434 使用 SPL XLL sp…

拼多多商品详情商品标题sku等信息抓取接口API调用步骤演示

接口名称&#xff1a;item_get_app_pro 公共参数 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址中&#xff09;[item_search,item_get,item_search_sho…

两台电脑怎么互传文件?这些方法你值得一试

在日常生活和工作中&#xff0c;我们经常需要在不同电脑之间传输文件&#xff0c;这可能是文档、照片、音乐或其他类型的文件。两台电脑怎么互传文件是非常有用的技能&#xff0c;可以提高工作效率并简化文件共享过程。本文将介绍三种常见的方法&#xff0c;帮助您了解如何在两…

苹果手机怎么看海拔高度?快速掌握使用技巧

手机不仅能满足我们日常的通讯需求&#xff0c;还内置了许多实用的功能&#xff0c;其中包括查看海拔高度。无论是登山、徒步、骑行还是只是好奇地想要了解所在地的海拔高度&#xff0c;苹果手机都能够满足您的需求。苹果手机怎么看海拔高度&#xff1f;在本文中&#xff0c;我…

wps能打开caj文件吗?CAJ应该如何打开?caj转pdf

问题1&#xff1a;wps能打开caj文件吗&#xff1f; WPS不能直接打开CAJ文件。 CAJ是中国知网开发的一种文件格式&#xff0c;主要用于存储学术文献&#xff0c;需要使用专门的阅读器才能打开。 问题2&#xff1a;CAJ应该如何打开&#xff1f; 要打开CAJ文件&#xff0c;你可…

羧甲基纤维素钠(CMC-Na)市场规模不断增长 我国生产企业众多

羧甲基纤维素钠&#xff08;CMC-Na&#xff09;市场规模不断增长 我国生产企业众多 羧甲基纤维素钠&#xff08;CMC-Na&#xff09;又称CMC-钠&#xff0c;化学式为[C6H7O2&#xff08;OH&#xff09;2OCH2COONa]n&#xff0c;是一种离子型纤维素醚。CMC-Na外观呈白色颗粒状或纤…

柳宗元,政治坎坷与文学辉煌的交织

&#x1f4a1; 如果想阅读最新的文章&#xff0c;或者有技术问题需要交流和沟通&#xff0c;可搜索并关注微信公众号“希望睿智”。 柳宗元&#xff0c;字子厚&#xff0c;生于唐代宗大历年间&#xff08;公元773年&#xff09;&#xff0c;卒于唐宪宗元和年间&#xff08;公元…

【全开源】在线题库微信小程序系统源码(ThinkPHP+FastAdmin+UniApp)

打造个性化学习平台 一、引言&#xff1a;在线学习的未来趋势 在数字化时代&#xff0c;线上学习已逐渐成为主流。随着移动互联网的普及&#xff0c;小程序以其轻便、快捷、无需安装的特点&#xff0c;成为用户日常学习的新选择。为了满足广大用户对于在线学习的需求&#xf…

光学测量反射率定标版

在光学测量和成像领域&#xff0c;准确性和一致性是至关重要的。为了确保设备能够提供可靠的数据&#xff0c;必须对其进行精确的校准。这就是反射率定标版发挥作用的地方。本文将深入探讨反射率定标版的概念、重要性、使用方式以及它们如何帮助科学家和工程师实现光学测量的精…

LeetCode刷题之HOT100之最长回文串

2024/5/28 大家上午好啊&#xff0c;我又来做题了 1、题目描述 2、逻辑分析 题目要求找出最长的回文子串。我回去看了一下回文数字和回文链表这两道题。这个题目的思想其实跟以上两题也差不多&#xff0c;但是结合了最长子串这一概念。那么怎么解决这个题目呢&#xff1f;那么…

Spark Sql写代码方式(yarn)以及 spark sql整合hive详解

引入部分&#xff1a;通常我们在IDEA中写spark代码中如果设置了loacl参数&#xff0c;基本都是在IDEA本地运行&#xff0c;不会提交到 standalone或yarn上运行&#xff0c;在前几篇文章中写的大多数都是该种形式的spark代码&#xff0c;但也写到了如何将spark代码提交到standal…

【VTKExamples::Utilities】第六期 DataAnimation

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 公众号:VTK忠粉 前言 本文分享VTK样例DataAnimation,并解析接口vtkProgrammableFilter,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U…

Windows远程桌面是什么?

Windows远程桌面是一种远程桌面协议&#xff0c;允许用户通过网络连接到远程Windows计算机&#xff0c;并在本地操作远程计算机。它为用户提供了访问远程计算机的便利性&#xff0c;可以在不同地区的电脑或设备之间进行信息远程通信。 天联解决方案 在远程桌面技术中&#xff…

制作ARM架构 docker镜像

docker简介 docker客户端 Docker 客户端有两种替代选项:名为 docker 的命令行应用程序或名为 Docker Desktop 的基于图形用户界面 (GUI) 的应用程序。 CLI 和 Docker Desktop 均与 Docker 服务器交互。 来自 CLI 或 Docker Desktop 的 docker 命令使用 Docker REST API 将指…

KAN(Kolmogorov-Arnold Network)的理解 1

系列文章目录 第一部分 KAN的理解——数学背景 文章目录 系列文章目录前言KAN背后的数学原理&#xff1a;Kolmogorov-Arnold representation theorem 前言 这里记录我对于KAN的探索过程&#xff0c;每次会尝试理解解释一部分问题。欢迎大家和我一起讨论。 KAN tutorial KAN背…

NVIDIA AGX Orin/Jetson 平台+GMSL 车载AI视觉方案——索尼车载1700万超高像素前视摄像头

推出“1700万超高像素前视摄像头”以及基于该摄像头的“智驾超级视觉5V方案”&#xff0c;该摄像头采用索尼1700万像素IMX735车载图像传感器&#xff0c;搭载水平120度超大广角镜头和出色的超高速传输技术&#xff0c;是行业革命性创新产品&#xff0c;在车展上备受关注。 索尼…

mysql实战——mysql5.7保姆级安装教程

1、上传 上传5.7压缩包到/usr/local目录下 2、解压 cd /usr/local tar -zxvf mysql--5.7.38-linux-glibc2.12-x86_64.tar.gz mv mysql-5.7.38-linux-glibc2.12-x86_64/ mysql 3、创建mysql用户组和用户 groupadd mysql useradd -g mysql mysql 4、创建数据目录data&#xf…

git冲突

git冲突的产生&#xff1a; 首先用户A新建一个文件conflict&#xff0c;并在里面添加内容 然后通过add,commit,push将该文件上传到远端仓库 然后用户B通过pull将程序拉下来之后&#xff0c;也在这个文档里面进行编辑&#xff0c;并且内容不一样 如果这个时候其中一个人push&…