Linux进程通信——信号(二)

news2024/11/26 2:27:41

信号处理函数的注册

信号处理函数的注册不只一种方法,分为入门版和高级版
1.入门版: 函数 signal
2.高级版:函数 sigection

信号处理发送函数

信号发送函数也不止一个,同样分为入门版和高级版
1.入门版: 函数 kill
2.高级版: 函数 sigqueue

sigaction函数

作用

sigaction函数是一个系统调用,可以用来查询或设置信号处理方式

头文件

#include <signal.h>

函数原型

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

参数解读

signum参数指出要捕获的信号类型
act参数指定新的信号处理方式,struct sigaction类型如果不为空说明需要对该信号有新的配置(函数原型是指针,输入参数时应输入地址)
oldact

备份

1.如果不为空,那么可以对之前的信号配置进行备份,以方便之后进行恢复

2.如果为空,直接输入NULL

struct sigaction结构体

函数原型

struct sigaction
{
   void (*sa_handler)(int); //信号处理程序,不接受额外数据,SIG_IGN 为忽略,SIG_DFL 为默认动作
   void (*sa_sigaction)(int, siginfo_t *, void *); //信号处理程序,能够接受额外数据和sigqueue配合使用
   sigset_t sa_mask;//阻塞关键字的信号集,可以再调用捕捉函数之前,把信号添加到信号阻塞字,信号捕捉函数返回之前恢复为原先的值。
   int sa_flags;//影响信号的行为SA_SIGINFO表示能够接受数据
 };
//若调用该结构体,则sa_handler和sa_sigaction只能选择其中一个,即两个不能同时存在

参数解读

sa_handler:与前一章节中的handler相同,代表新的信号处理函数,但不能接受额外数据。

sa_sigaction:信号处理程序,代表新的信号处理函数,能够接受额外数据,需配合sigqueue函数

int这里的int一般是信号函数类型(编号),如int signum
siginfo_t *用于接受信号,功能比较多样化,如siginfo_t *info
void *接收到信号所携带的额外数据,是否为NULL可以判断是否携带额外数据,如void *context

siginfo为结构体,其中后面跟的是指针,在调用时应注意结构体指针的书写格式(->),下面是该结构体的具体成员。

 siginfo_t
{
               int      si_signo;    /* Signal number */
               int      si_errno;    /* An errno value */
               int      si_code;     /* Signal code */
               int      si_trapno;   /* Trap number that caused
                                        hardware-generated signal
                                        (unused on most architectures) */
               pid_t    si_pid;      /* Sending process ID */
               uid_t    si_uid;      /* Real user ID of sending process */
               int      si_status;   /* Exit value or signal */
               clock_t  si_utime;    /* User time consumed */
               clock_t  si_stime;    /* System time consumed */
               sigval_t si_value;    /* Signal value */
               int      si_int;      /* POSIX.1b signal */
               void    *si_ptr;      /* POSIX.1b signal */
               int      si_overrun;  /* Timer overrun count; POSIX.1b timers */
               int      si_timerid;  /* Timer ID; POSIX.1b timers */
               void    *si_addr;     /* Memory location which caused fault */
               int      si_band;     /* Band event */
               int      si_fd;       /* File descriptor */
}

其中的成员很多,si_signosi_code 是必须实现的两个成员。可以通过这个结构体获取到信号的相关信息
关于发送过来的数据是存在两个地方的,sigval_t si_value这个成员中有保存了发送过来的信息;
同时,在si_int或者si_ptr成员中也保存了对应的数据。

sa_mark:用来设置在处理该信号时暂时将sa_mask 指定的信号集搁置

调用该函数后,会在捕捉函数调用前设置为阻塞,并在捕捉函数返回时恢复默认原有设置。这样的目的是,在调用信号处理函数时,就可以阻塞默写信号了。在信号处理函数被调用时,操作系统会建立新的信号阻塞字,包括正在被递送的信号。因此,可以保证在处理一个给定信号时,如果这个种信号再次发生,那么他会被阻塞到对之前一个信号的处理结束为止

sa_flags:用来设置信号处理的其他相关操作,下列的数值可用

SA_RESETHAND当调用信号处理函数时,将信号的处理函数重置为缺省值SIG_DFL
SA_RESTART如果信号中断了进程的某个系统调用,则系统自动启动该系统调用
SA_NODEFER一般情况下, 当信号处理函数运行时,内核将阻塞该给定信号。但是如果设置了 SA_NODEFER标记, 那么在该信号处理函数运行时,内核将不会阻塞该信号

但由于我们需要接受数据,所以这里我们经常使用的数值是SA_SIGINFO

sigqueue函数

作用

在队列中向指定进程发送一个信号和数据

头文件

#include <signal.h>

函数原型

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

参数解读

pid信号发送目标位置的进程号,可用ps查看或者直接调用getpid()打印出来
sig所发送的信号类型,如SIGUUSR1
value信号附带的数据,即传送的内容是什么,是一个联合体

union sigval联合体

union sigval
{
   int   sival_int;//传递的数据可以是整型数
   void *sival_ptr;//指向要传递的信号参数
 };

注意事项

1、使用 sigaction 函数安装信号处理程序时,需先写入 SA_SIGINFO 标志才可以接受数据。
2、sigaction 结构体中的sa_sigaction成员提供了信号捕捉函数。如果实现的sa_handler成员,那么将无法获取额外携带的数据
3、sigqueue 函数只能把信号发送给单个进程,可以使用 value 参数向信号处理程序传递整数值或者指针值。

代码示例

sigcation.c

#include <stdio.h>
#include <signal.h>

void handler(int signum,siginfo_t *info,void *context)
{
	printf("the signum is %d\n",signum);
	if(context != NULL)//信号携带内容,将内容打印出来
	{
		printf("get context is %d\n",info->si_int);//内容为整型数,整型数打印有两种方法 第一种是直接打印整型数,第二种是调用共用体中的整型数打印
		printf("get context is %d\n",info->si_value.sival_int);
		printf("send pid is %d\n",info->si_pid);
	}
}

int main()
{
	struct sigaction act;

	printf("pid is %d\n",getpid());	

	act.sa_sigaction = handler;//信号处理函数调用
	act.sa_flags = SA_SIGINFO;//设置为可接收数据
	
	sigaction(SIGUSR1,&act,NULL);//第二个参数是指针,应输入地址,第三个参数是备份,不需要则写入NULL

	while(1);
	return 0;
}

sigqueue.c

#include <stdio.h>
#include <signal.h>

int main(int agrc,char **agrv)
{
	int pid = atoi(agrv[1]);
	int signum =atoi(agrv[2]);

	union sigval value;
	value.sival_int = 999;//信号内容设置为999

	sigqueue(pid,signum,value);

	printf("pid is %d\n",getpid());
	puts("done");
	return 0;
}

先将sigaction.c的进程号打印出来后会等待接受数据,接着调用sigqueue.c将其自身进程号打印出来,并做信号处理,将携带内容发送至sigaction.c,sigaction.c接受到数据后将数据打印出来。实现了在一端发送信号,在另一端接收信号。

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

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

相关文章

图解系列--Http

1.URI和URL 1.1.URL URL是统一资源定位符。URL正是使用 Web 浏览器等访问 Web 页面时需要输入的网页地址。比如&#xff0c;http://hackr.jp/就是 URL。 1.2.URI 统一资源标识符。 URI 用字符串标识某一互联网资源&#xff0c;而URL表示资源的地点&#xff08;互联网上所处的位…

Unity 自带的一些可以操控时间的属性或方法。

今天来总结下Unity自带的一些可以操控时间的方法。 1、Time.time。比较常用计算运行时间而触发特定事件。 public class Controller : MonoBehaviour {public float eventTime 5f; // 触发事件的时间private float startTime; // 游戏开始的时间private void Start(){startT…

使用凌鲨进行接口联调

接口联调是指在软件开发过程中&#xff0c;不同的团队或模块之间进行接口协作的一种技术手段。它是研发过程中必不可少的一个环节&#xff0c;旨在确保不同模块之间的数据交互和功能调用能够顺畅进行&#xff0c;从而提升整个系统的稳定性和性能。 凌鲨中支持了GRPC&#xff0…

Sentry介绍与使用 - Issues模块

这篇文章是我在公司做 Sentry 相关分享的演讲稿。 大家好&#xff0c;现在由我来讲解 Sentry 的 Issues &#xff08;问题&#xff09;模块。我会分为三个部分来讲&#xff0c;首先我会介绍 Sentry 一些重要的概念&#xff0c;然后讲一下 Issues 的基本使用方式&#xff0c;最后…

【Java】线程池的简单实用

1、什么是线程池 Java当中&#xff0c;为了规避频繁创建调度进程的开销&#xff0c;我们引入了线程。但是如果进一步提高创建销毁频率&#xff0c;线程的开销也不容忽视。 对此我们有两个解决方案 协程&#xff08;轻量级线程&#xff09;&#xff1a;相比线程&#xff0c;把…

Cache学习(4):Cache分配策略Cache更新策略Cache逐出策略

Cache的数据流 常用名词 Allocation 分配Eviction 驱逐分配策略和更新策略分别为当产生Cache miss和Cache hit的时候数据流的具体行为 1 Cache分配策略&#xff08;Cache Allocation Policy&#xff09; Cache的分配策略是指不同情况下为数据分配Cache Line的不同行为。Cac…

2018年8月28日 Go生态洞察:Go 2草案设计初探

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

基于springboot+mysql实现的小区物业管理系统

基于springbootmysql实现的小区物业管理系统,演示地址:登录 演示账号&#xff1a;用户名:744621980qq.com 密码:123456,主要包含房屋管理(楼栋管理&#xff0c;单元管理&#xff0c;房屋管理)&#xff0c;车位管理&#xff0c;缴费管理&#xff0c;社区服务( 公告管理&#xf…

2023年程序设计迎新赛(第二届个人程序设计大赛)

7-1 找规律 请从所给的四个选项中&#xff0c;选择最合适的一个填入问号处&#xff0c;使之呈现一定的规律性。 输入格式: 无 输出格式: 大写字母 输入样例: 输出样例: #include<stdio.h> int main(){printf("D");return 0; }7-2 蜡烛燃烧时间 有粗细不同…

使用HTML+CSS+JS网页设计与制作,酷炫动效科技农业网页

使用HTMLCSSJS网页设计与制作&#xff0c;酷炫动效科技农业网页。 可以用于家乡介绍、科技农业、图片画廊展示等个人网站的设计与制作。农业网站、家乡网站、农产品网站、旅游网站。 网站亮点 1、视觉设计&#xff1a;排版布局极简设计&#xff0c;优质的视觉体验等。 2、动…

java小游戏之【王者荣耀】

首先创建一个新的Java项目命名为“王者荣耀”&#xff0c;并在src下创建两个包分别命名为“com.sxt"、”com.stx.beast",在相应的包中创建所需的类。 代码 package com.sxt;import javax.swing.*; import java.awt.*;public class Background extends GameObject {p…

以非常规思维去做一个嵌入式音视频开发项目!

前言&#xff1a; 大家好&#xff0c;在上周的文章里面&#xff0c;给大家介绍了一个音视频项目&#xff0c;本周继续来分享音视频项目&#xff0c;之前说过&#xff0c;如果你不知道做什么功能开发嘛&#xff0c;因为接触的少&#xff1b;我突然想到&#xff0c;可以去参考市面…

win10下载Remix IDE桌面版以及空白页面的解决

文章目录 Remix IDE 的下载Remix IDE 空白页面的解决 Remix IDE 的下载 到 github 地址 https://github.com/ethereum/remix-desktop/releases 选择exe文件或根据自己电脑版本选择对应的zip文件进行下载&#xff0c;然后正常安装即可。 Remix IDE 空白页面的解决 有时打开Remix…

容器技术——Cgroup

目录 容器技术容器技术概述要区分好共享与隔离的概念容器技术的三大核心容器对比虚拟机 namespaceUnionFs容器操作系统的来源操作系统的来源完整操作系统的镜像docker image是什么&#xff1f;如何构成的 如何为容器安装操作系统UnionFS&#xff08;联合文件系统&#xff09;的…

Echart力引导依赖关系布局图

Echarts ECharts&#xff08;Enterprise Charts&#xff09;Apache ECharts是百度开发的一款开源的 JavaScript 数据可视化库。它提供了丰富的图表和图形&#xff0c;适用于在 Web 应用程序中创建各种交互式和动态的数据可视化图表。ECharts支持各种图表类型&#xff0c;包括折…

【LeetCode】挑战100天 Day17(热题+面试经典150题)

【LeetCode】挑战100天 Day17&#xff08;热题面试经典150题&#xff09; 一、LeetCode介绍二、LeetCode 热题 HOT 100-192.1 题目2.2 题解 三、面试经典 150 题-193.1 题目3.2 题解 一、LeetCode介绍 LeetCode是一个在线编程网站&#xff0c;提供各种算法和数据结构的题目&…

Hugging Face宣布最受欢迎的AI机构,开源模型ChatGLM-6B广受认可

近日&#xff0c;Hugging Face作为开源AI社区的代表&#xff0c;总结了社区最欢迎的前15个公司和机构&#xff0c;几乎囊括了全部国内外风头正盛的AI科技机构&#xff0c;Stability AI、Meta AI、Runway占据排名前三&#xff0c;大众熟知的OpenAI、谷歌、微软也榜上有名。 其中…

算法通关村-----字符串冲刺题

最长公共前缀 问题描述 编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀&#xff0c;返回空字符串 “”。详见leetcode14 问题分析 直观上来看&#xff0c;有竖直和水平两种方式&#xff0c;竖直方式是指我们依次比较所有字符串的第一个字符&#xff0c;…

数据库基础教程之序列自增设置(三)

点击public来选择一个模式。 选择其他-》序列。 选择新建序列。 设置序列参数&#xff08;最大值不超过2的63次方-1&#xff09;。 点击保存。 刷新序列列表&#xff0c;可以看见新建序列。 设置主键自增 打开设计表-》选中字段-》默认值设置为&#xff1a;nextval(‘log_text’…

2024年最新最全的Jmeter接口测试必会知识点:jmeter连接数据库

jmeter连接mysql数据库 大致步骤如下&#xff1a; 1、下载mysql的jar包放入到jmeter的lib下&#xff0c;然后重启jmeter 2、配置JDBC Connection Configuration 3、配置JDBC Request 4、在请求中引用查询到的结果变量&#xff0c;可以结合计数器取每一个结果值&#xff1a…