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

信号

信号也是IPC中的一种,是和管道,消息队列,共享内存并列的概念。

本文参考:

Linux中的信号_linux中信号_wolf鬼刀的博客-CSDN博客

Linux系统编程(信号处理 sigacation函数和sigqueue函数 )_花落已飘的博客-CSDN博客

Linux的sigqueue函数_linux sigqueue_QtHalcon的博客-CSDN博客

概念

信号是进程之间异步通知的一种方式,属于软中断;

可以使用“kill -l”来查看系统定义的信号列表:

 在这里插入图片描述

所以,当在终端输入“crtl + c”时,其实就是调用了2号SIGINT,使用信号机制停止了一个程序。

  • 从图中可以看到每个信号都有一个编号宏定义的名称,这些宏都可以在signal.h中找到
  • 注意并不是一共有64个信号,自己仔细看,共有62种信号
  • 31号信号之前都是不可靠信号,也是非实时信号
  • 编号34以上的是实时信号,可靠信号,各种信号各自在什么条件下产生什么默认的动作都可以在signal(7)中查看

同时kill命令还可以用来执行命令,例如一个进程的PID号为1234,则可以使用“kill 9 1234”或“kill SIGKILL 1234” 来杀死这个进程

另外,kill不仅可以使用在命令窗口,kill还可以作为一个API

kill函数 : 给一个指定的进程发送一个指定的信号

包含的头文件:

#include <sys/types.h>
#include <signal.h>

函数原型:

int kill(pid_t pid, int sig);

函数参数:

  • pid:进程号
  • sig:信号编号

信号的处理方式

  • 忽略信号(SIGKILL和SIGSTOP无法被忽略
  • 执行给信号的默认动作
  • 提供一个信号处理函数,要求用户在处理该信号时切换到用户态去执行处理函数,即捕捉信号

其中,对于用户来说,信号更多的意义是实现异步操作,也就是捕捉信号,其核心就是编写“信号处理函数”

信号处理的API函数及应用

signal函数

用来自定义信号处理方式

需要包含的库

#include <signal.h>

函数原型

typedef void (*sighandler_t)(int); //一个指向“传入参数是int 返回值是void的函数”,名为“sighandler_t”的指针sighandler_t signal(int signum, sighandler_t handler);

函数参数

  • signum:信号编号
  • handler:函数指针,指向信号处理函数;也可以使用宏,比如使用“SIG_IGN”,则忽略信号

使用举例1

signal1.c:
#include <signal.h>
#include <stdio.h>void sighandler(int sig)
{printf("get signal:%d\n",sig);}int main()
{signal(2,sighandler);while(1);return 0;
}

可见,当捕获了信号2之后,在键盘输入“ctrl + c” 不再会执行默认动作来结束进程,而是被程序捕获,并执行了信号处理函数

那么此时如何退出进程呢?可以使用刚刚提到的kill指令,先搜索pid号然后直接杀死进程

 

使用举例2 

同样,也可以在程序中直接调用kill函数来发送信号

signal2.c:

编写一个C程序实现“向自己发送指定信号”的功能

#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>void sighandler(int sig)
{printf("get signal:%d\n",sig);}int main(int argc,char **argv)
{int signum;pid_t pid;signum = atoi(argv[1]); //由于从键盘接收的是字符串,所以要使用“atoi”函数将ASCII码转为整型数pid = getpid();signal(2,sighandler); //为了实现效果,一定要先执行signal,再执行killkill(pid,signum);while(1);return 0;
}

编译运行代码并指定第二个参数为2: 

 

可见,虽然此时没有在键盘打出 “ctrl + c”,但是内部的代码调用了kill对自己发送了2号信号,所以同样实现了刚刚的效果。

学到了这里,一定会产生疑问:为什么信号会作为IPC中的一员,如果只是发送信号的话,不应该算是一种很有效的进程通讯方式,所以信号的处理还有更高级的方法,也就是带消息的高级信号操作,既然要带消息,那么就需要使用更高级的API函数来实现收发:

  • 发送信号:使用sigqueue函数
  • 接收信号:使用sigaction函数

sigaction函数

实现带消息的高级信号操作,可以接收带消息的信号

需要包含的库

#include <signal.h>

函数原型

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

函数参数

  • signum:信号编号
  • act:指定新的信号处理方式
  • oldact:输出先前信号的处理方式(如果不为NULL的话)

struct sigaction结构体介绍(sigaction函数的第二个参数)

struct sigaction {void (*sa_handler)(int);void (*sa_sigaction)(int, siginfo_t *, void *);sigset_t sa_mask;int sa_flags;void (*sa_restorer)(void);
}
  • sa_handler:此参数和signal()的参数handler相同,代表新的信号处理函数,如果使用这个成员参数,那就和signal函数无异了
  • sa_sigaction:带消息的信号处理函数

int:第一个参数是信号编号

siginfo_t *:第二个参数是一个结构体,包括si_signo,si_code,si_int,si_value等等各种成员,其中si_signo和si_code必须实现

void *:第三个参数是一个指针,用来指示是否有消息存在,如果为NULL则无消息,否则就有消息

  • sa_mask:用来设置在处理该信号时暂时将sa_mask 指定的信号集搁置,可以理解为处理信号的时候释放阻塞(默认阻塞)
  • sa_flags:用来设置信号处理的其他相关操作,可以是以下值的“按位或”组合:

 ◆ SA_RESTART:使被信号打断的系统调用自动重新发起
 ◆ SA_NOCLDSTOP:使父进程在它的子进程暂停或继续运行时不会收到 SIGCHLD 信号
 ◆ SA_NOCLDWAIT:使父进程在它的子进程退出时不会收到 SIGCHLD 信号,这时子进程如果退出也不会成为僵尸进程
 ◆ SA_NODEFER:使对信号的屏蔽无效,即在信号处理函数执行期间仍能发出这个信号
 ◆ SA_RESETHAND:信号处理之后重新设置为默认的处理方式
 ◆ SA_SIGINFO:使用 sa_sigaction 成员而不是 sa_handler 作为信号处理函数(重要

  • re_restorer:是一个已经废弃的数据域,不使用 

sigqueue函数

发送带消息的信号

成功使用sigqueue这个函数需要有两个前提:

  • sigaction函数的第二个参数结构体中的sa_flags成员必须有“SA_SIGINFO
  • sigaction函数的第二个参数结构体中实现的是成员sa_sigaction函数而不是成员sa_handler函数

需要包含的库

#include <signal.h>

函数原型

int sigqueue(pid_t pid, int sig, const union sigval value);

函数参数 

  • pid:目标进程的进程号
  • sig:要发送的信号的编号
  • value:要附带发送的消息

value的类型是一个名为sigval的联合体,如果需要附带的消息是整型,则将数据存入成员“sival_int”;而如果消息类型是字符串,则存入成员“sival_ptr"

union sigval {int   sival_int;void *sival_ptr;
};

使用sigaction和sigqueue的实操演示

需求:编写两个C程序,一个使用sigaction来接收,一个使用sigqueue来发送,实现带消息的信号的通讯

signal3.c:(接收带消息的信号)

#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>void sighandler(int sig, siginfo_t *info, void *context)
{printf("get signal:%d\n",sig);if(context != NULL){printf("get data = %d\n",info->si_int);//printf"(get data = %d\n",info->si_value.sival_int);}}int main()
{struct sigaction act;act.sa_sigaction = sighandler;act.sa_flags = SA_SIGINFO;sigaction(2,&act,NULL);while(1);return 0;
}

signal4.c:(发送带消息的信号)

#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>int main(int argc,char **argv)
{int signum;pid_t pid;int data;pid = atoi(argv[1]);signum = atoi(argv[2]);data = atoi(argv[3]);union sigval value;value.sival_int = data;	sigqueue(pid,signum,value);printf("signal no.%d has been sent to pid %d, context:%d\n",signum,pid,data);return 0;
}

实现效果:

 首先编译并运行signal3.c

可见,此时没有接收到任何信号,一直阻塞

此时新开一个窗口先查询到这个signal3.c的进程号

然后根据进程号,编译并运行signal4.c,将编号为2的信号发送到signal3.c对应的进程,并附带55的整型消息

此时再回看signal3.c的运行界面 

 

可见,此时不仅收到了来自signal4.c的信号,还收到了附带的整型数据消息 

相关文章:

信号

信号也是IPC中的一种&#xff0c;是和管道&#xff0c;消息队列&#xff0c;共享内存并列的概念。 本文参考&#xff1a; Linux中的信号_linux中信号_wolf鬼刀的博客-CSDN博客 Linux系统编程&#xff08;信号处理 sigacation函数和sigqueue函数 )_花落已飘的博客-CSDN博客 Linu…...

产品经理的真实薪资有多少?今天带你看看

作为产品经理&#xff0c;除了需要拥有扎实的技术背景和出色的产品设计能力&#xff0c;还需具备出色的领导力和商业敏感度。因此&#xff0c;产品经理的薪资也越来越成为人们关注的话题。那么&#xff0c;一般来说&#xff0c;产品经理的薪资水平如何呢&#xff1f; 薪资多少…...

《一个操作系统的实现》windows用vm安装CentOS——从bochs环境搭建到第一个demo跑通

vm安装CentOS虚拟机带有桌面的版本。su输入密码123456。更新yum -y update 。一般已经安装好后面这2个工具&#xff1a;yum install -y net-tools wget。看下ip地址ifconfig&#xff0c;然后本地终端连接ssh root192.168.249.132输入密码即可&#xff0c;主要是为了复制网址方便…...

线程Thread

文章目录 一、概念1、进程2、线程3、CPU与线程的关系4、并行、并发5、线程的生命周期 二、创建1、继承Thread2、实现Runnable接口3、实现Callable接口 三、API1、获取运行使用的线程2、唯一标识3、线程名4、优先级5、是否处于活动状态6、守护线程7、join1、API2、有无join对比 …...

如何使用CSS实现一个渐变背景效果?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 使用CSS实现渐变背景效果⭐ 线性渐变&#xff08;Linear Gradient&#xff09;⭐ 径向渐变&#xff08;Radial Gradient&#xff09;⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订…...

初始C语言(7)——详细讲解有关初阶指针的内容

系列文章目录 第一章 “C“浒传——初识C语言&#xff08;1&#xff09;&#xff08;更适合初学者体质哦&#xff01;&#xff09; 第二章 初始C语言&#xff08;2&#xff09;——详细认识分支语句和循环语句以及他们的易错点 第三章 初阶C语言&#xff08;3&#xff09;——…...

ArcGIS Pro技术应用(暨基础入门、制图、空间分析、影像分析、三维建模、空间统计分析与建模、python融合、案例应用)

GIS是利用电子计算机及其外部设备&#xff0c;采集、存储、分析和描述整个或部分地球表面与空间信息系统。简单地讲&#xff0c;它是在一定的地域内&#xff0c;将地理空间信息和 一些与该地域地理信息相关的属性信息结合起来&#xff0c;达到对地理和属性信息的综合管理。GIS的…...

RISC-V公测平台发布 · 数据库在RISC-V服务器上的适配评估

前言 上一期讲到YCSB在RISC-V服务器上对MySQL进行性能测试&#xff08;RISC-V公测平台发布 使用YCSB测试SG2042上的MySQL性能&#xff09;&#xff0c;在这一期文章中&#xff0c;我们继续深入讨论RISC-V数据库的应用。本期就继续利用HS-2平台来测试数据库软件在RISC-V服务器…...

UE5.2 LyraDemo源码阅读笔记(五)输入系统

Lyra里使用了增强输入系统&#xff0c;首先知道增强输入系统里的三个类型配置。 一、Input Actions (IA)&#xff1a; 输入操作带来的变量&#xff0c;与玩家的输入组件绑定&#xff0c;回调里驱动玩家行为。 二、InputMappingContext&#xff08;IMC&#xff09;&#xff1a…...

线段树详解——影子宽度

OK&#xff0c;今天来讲一讲线段树~~ 线段树是什么线段树的实现线段树的时间复杂度线段树的应用线段树的节点结构其他操作和优化例题——影子宽度输入输出格式输入格式输出格式 输入输出样例输入样例输出样例 例题讲解 线段树是什么 线段树&#xff08; S e g m e n t Segmen…...

使用R语言绘制折线图

写在前面 昨天我们分享了使用Python绘制折线图的教程,跟着NC学作图 | 使用python绘制折线图,考虑到很多同学基本不使用Python绘图。那么,我们也使用R语言复现此图形。 此外,在前期的教程中,我们基本没有分享过折线图的教程。因此,我们在这里也制作一期关于折线图的教程。…...

无涯教程-Perl - wantarray函数

描述 如果当前正在执行的函数的context正在寻找列表值,则此函数返回true。在标量context中返回false。 语法 以下是此函数的简单语法- wantarray返回值 如果没有context,则此函数返回undef&#xff1b;如果lvalue需要标量,则该函数返回0。 例 以下是显示其基本用法的示例…...

【gitkraken】gitkraken自动更新问题

GitKraken 会自动升级&#xff01;一旦自动升级&#xff0c;你的 GitKraken 自然就不再是最后一个免费版 6.5.1 了。 在安装 GitKraken 之后&#xff0c;在你的安装目录&#xff08;C:\Users\<用户名>\AppData\Local\gitkraken&#xff09;下会有一个名为 Update.exe 的…...

《Java Web程序设计》试卷03

《Java Web程序设计》试卷03 课程编码&#xff1a; 301209 适用专业&#xff1a; 计算机应用(包括JAVA方向) 注 意 事 项 1、首先按要求在试卷标封处填写你所在的系&#xff08;部&#xff09;、专业、班级及学号和姓名&#xff1b; 2、仔细阅读各类题目的回答要求&#xff0c;…...

怎么查看小程序中的会员信息

商家通过查看会员信息&#xff0c;可以更好地了解用户&#xff0c;并为他们提供更个性化的服务和推荐。接下来&#xff0c;就将介绍如何查看会员信息。 商家在管理员后台->会员管理处&#xff0c;可以查看到会员列表。支持搜索会员的卡号、手机号和等级。还支持批量删除会员…...

网络安全—黑客—自学笔记

想自学网络安全&#xff08;黑客技术&#xff09;首先你得了解什么是网络安全&#xff01;什么是黑客&#xff01; 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全…...

深度解读波卡 2.0:多核、更有韧性、以应用为中心

本文基于 Polkadot 生态研究院整理&#xff0c;有所删节 随着波卡 1.0 的正式实现&#xff0c;波卡于 6 月 28 日至 29 日在哥本哈根举办了年度最重要的会议 Polkadot Decoded 2023&#xff0c;吸引了来自全球的行业专家、开发者和爱好者&#xff0c;共同探讨和分享波卡生态的…...

微服务中间件--Eureka注册中心

Eureka注册中心 a.eureka原理分析b.搭建eureka服务c.服务注册d.服务发现 a.eureka原理分析 1.每个服务启动时&#xff0c;将自动在eureka中注册服务信息 (每个服务每隔30秒发送一次的心跳续约&#xff0c;当某个服务没有发送时&#xff0c;eurekaServer将自动剔除该服务&#x…...

积跬步至千里 || 矩阵可视化

矩阵可视化 矩阵可以很方面地展示事物两两之间的关系&#xff0c;这种关系可以通过矩阵可视化的方式进行简单监控。 定义一个通用类 from matplotlib import pyplot as plt import seaborn as sns import numpy as np import pandas as pdclass matrix_monitor():def __init…...

zookeeper详细介绍

ZooKeeper是一个开源的分布式协调服务,具有以下一些关键特点: 数据模型 ZooKeeper的数据模型采用层次化的多叉树形结构,每个节点称为znode,类似于文件系统中的文件和目录。每个znode可以存储数据和控制信息。一致性保证 ZooKeeper通过ZAB协议,实现分布式环境下数据的强一致性,…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

【JavaEE】-- HTTP

1. HTTP是什么&#xff1f; HTTP&#xff08;全称为"超文本传输协议"&#xff09;是一种应用非常广泛的应用层协议&#xff0c;HTTP是基于TCP协议的一种应用层协议。 应用层协议&#xff1a;是计算机网络协议栈中最高层的协议&#xff0c;它定义了运行在不同主机上…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)

可以使用Sqliteviz这个网站免费编写sql语句&#xff0c;它能够让用户直接在浏览器内练习SQL的语法&#xff0c;不需要安装任何软件。 链接如下&#xff1a; sqliteviz 注意&#xff1a; 在转写SQL语法时&#xff0c;关键字之间有一个特定的顺序&#xff0c;这个顺序会影响到…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...