LINUX进程间的通信(IPC)--信号

news2024/9/9 4:54:20

一、概念

信号通信,其实就是内核向用户空间进程发送信号,只有内核才能发信号,用户空间进程不能发送信号。信号已经是存在内核中的了,不需要用户自己创建。

信号通信的框架
        * 信号的发送(发送信号进程):kill raise alarm
        * 信号的接收(接收信号进程) : pause() sleep while(1)
        * 信号的处理(接收信号进程) :signal

二、相关函数

1.信号的发送(发送信号进程)

所需头文件:
#include<signal.h>
#include<sys/types.h>
函数原型: int kill(pid_t pid, int sig);
参数:
函数传入值: pid
        正数:要接收信号的进程的进程号
        0:信号被发送到所有和 pid 进程在同一个进程组的进程
        ‐1:信号发给所有的进程表中的进程 ( 除了进程号最大的进程外 )
sig :信号
函数返回值:成功 0 出错 ‐1
示例:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>


int main(int argc,char *argv[])
{
        int pid,sig;
        if(argc != 3)
        {
                printf("输入错误\n");
                return -1;
        }
        sig = atoi(argv[1]);
        pid = atoi(argv[2]);

        printf("pid = %d,sig = %d\n",pid,sig);

        int rnt = kill(pid,sig);
        if(rnt == 0)
        {
                printf("杀死进程%d成功\n",pid);
        }

        return 0;
}
~   
运行结果:

2.raise: 发信号给自己 == kill(getpid(), sig)

所需头文件:
#include<signal.h>
#include<sys/types.h>
函数原型: int raise(int sig);
参数:
函数传入值: sig :信号
函数返回值:
成功 0 出错 ‐1
示例:
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
        printf("hello;\n");


        //int rnt = raise(9);
        int rnt = kill(getpid(),9);
        if(rnt == 0)
        {
                printf("杀死自己成功\n");
        }

        printf("world\n");
        return 0;
}

运行结果:

3.alarm : 发送闹钟信号的函数

alarm raise 函数的比较:
        相同点:让内核发送信号给当前进程
        不同点:
                alarm 只会发送SIGALARM 信号
                alarm 会让内核定时一段时间之后发送信号, raise 会让内核立刻发信号
所需头文件 #include <unistd.h>
函数原型 unsigned int alarm(unsigned int seconds)
参数:
seconds :指定秒数
返回值:
        成功:如果调用此alarm() 前,进程中已经设置了闹钟时间,则 返回上一个闹钟时间的剩余时间,否则返回 0
        出错:‐1
示例:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>

int main()
{
	int i;
	alarm(5);
	printf("alarm start\n");
	for(i =0 ;i<20;i++)
	{
		sleep(1);
		printf("i = %d\n",i);
	}

	return 0;
}

运行结果:

4.信号的接收

接收信号的进程,要有什么条件:要想使接收的进程能收到信号,这个进程不能结束 : sleep        
pause:进程状态为 S (休眠)
函数原型 int pause(void);
函数返回值:
成功: 0 ,出错: ‐1
示例:
#include <stdio.h>
#include <signal.h>
#include <unistd.h>

int main()
{
        int i,rnt;
        printf("pause start\n");
        pause();
        for(i =0 ;i<20;i++)
        {
                sleep(1);
                printf("i = %d\n",i);
        }
        return 0;
}

运行结果:

5.信号的处理

收到信号的进程,应该怎样处理? 处理的方式:
        1.进程的默认处理方式(内核为用户进程设置的默认处理方式)
                A:忽略B :终止进程 C: 暂停
        2.自己的处理方式:
                自己处理信号的方法告诉内核,这样你的进程收到了这个信号就会采用你自己的的处理方式、
函数原型 void (*signal(int signum, void (*handler)(int)))(int);
参数:
signum 指定信号
handler:
        1.SIG_IGN:忽略该信号。
        2.SIG_DFL:采用系统默认方式处理信号
        3.自定义的信号处理函数指针
函数返回值
成功:设置之前的信号处理方式
出错: ‐1
signal 函数有二个参数,第一个参数是一个整形变量(信号值),第二个参数是一个函数指针,是我们自己写的处理函
数;这个函数的返回值是一个函数指针。

1.示例:自定义的信号处理函数指针

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void myfun(int signum)
{
        int i;
        while(i<5)
        {
                printf("signum = %d,i = %d\n",signum,i);
                i++;
                sleep(1);
        }
}
int main()
{
        int i,rnt;
        signal(14,myfun);//14信号是定时器到时发出
        printf("alarm start\n");
        alarm(7);
        for(i =0 ;i<10;i++)
        {
                sleep(1);
                printf("i = %d\n",i);
        }
        return 0;
}

运行结果:
PS:回调函数执行完之后会重新回到主函数继续执行

2.示例:忽略该信号

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void myfun(int signum)
{
	int i;
	while(i<5)
	{
		printf("signum = %d,i = %d\n",signum,i);
		i++;
		sleep(1);
	}
}
int main()
{
	int i,rnt;
	signal(14,myfun);//14信号是定时器到时发出
	printf("alarm start\n");
	alarm(7);

	signal(14,SIG_IGN);
	for(i =0 ;i<10;i++)
	{
		sleep(1);
		printf("i = %d\n",i);
	}
	return 0;
}

运行结果:

3.示例:采用系统默认方式处理信号

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void myfun(int signum)
{
	int i;
	while(i<5)
	{
		printf("signum = %d,i = %d\n",signum,i);
		i++;
		sleep(1);
	}
}
int main()
{
	int i,rnt;
	signal(14,SIG_DFL);
	printf("alarm start\n");
	alarm(7);
	for(i =0 ;i<10;i++)
	{
		sleep(1);
		printf("i = %d\n",i);
	}
	return 0;
}

运行结果:

三、信号灯

信号灯集合(可以包含多个信号灯) IPC 对象是一个信号的集合(多个信号量) 一个信号灯有多个信号量。

1.相关函数

1.函数原型: int semget(key_t key, int nsems, int semflg);

功能:创建一个新的信号量或获取一个已经存在的信号量的键值。
函数参数:
key 和信号灯集关联的 key
nsems: 信号灯集中包含的信号灯数目
semflg 信号灯集的访问权限
函数返回值:
成功:信号灯集 ID
出错: ‐1

2.函数原型:int semctl ( int semid, int semnum, int cmd…union semun arg(不是地址));

功能:控制信号量,删除信号量或初始化信号量
函数参数:
semid :信号灯集 ID
semnum: 要修改的信号灯编号
cmd :
        GETVAL:获取信号灯的值
        SETVAL:设置信号灯的值
        IPC_RMID:从系统中删除信号灯集合
函数返回值:
成功: 0
出错: ‐1

三、PV操作

int semop(int semid ,struct sembuf *sops ,size_t nsops);
功能:用户改变信号量的值。也就是使用资源还是释放资源使用权
参数:
semid : 信号量的标识码。也就是 semget ()的返回值
sops 是一个指向结构体数组的指针。
        struct sembuf{
        unsigned short sem_num;   // 信号灯编号;
        short sem_op;                        //对该信号量的操作。‐1 ,P 操作, 1 V 操作
        short sem_flg;                        //0阻塞,1非阻塞
        };
sem_op : 操作信号灯的个数
// 如果其值为正数,该值会加到现有的信号内含值中。通常用于释放所控资源的使用权;如果 sem_op 的值为负 数,而其绝对值又大于信号的现值,操作将会阻塞,直到信号值大于或等于sem_op 的绝对值。通常用于获取资源的使用 权;如果sem_op 的值为 0 ,则操作将暂时阻塞,直到信号的值变为 0

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

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

相关文章

阿联酋云手机怎么做TikTok引流?

根据字节跳动广告资源的数据显示&#xff0c;2024年初&#xff0c;TikTok在阿联酋拥有1073万18岁及以上用户&#xff0c;其广告覆盖率达到当地互联网用户群的113%。从2023年初到2024年初&#xff0c;TikTok在阿联酋的潜在广告覆盖率增加了250万&#xff0c;增长率达30.4%。特别…

基于ant-design-vue3多功能操作表格,表头序号为动态添加记录按钮,鼠标在表格记录行,当前行序号显示删除按钮

由于项目需要&#xff0c;并考虑到尽可能让空间利用率高&#xff0c;因此定制开发一个表格组件&#xff0c;组件功能主要是在序号表头位置为添加按钮&#xff0c;点击按钮&#xff0c;新增一行表格数据&#xff1b;表格数据删除不同于以往表格在操作栏定义删除按钮&#xff0c;…

深度学习(概念相关)

深度学习&#xff08;论文相关&#xff09; 深度学习一些概念 通过阅读论文可以理解提取数据特征的重要性 深度学习学习怎么去提取特征 应用领域 深度学习应用&#xff1a; 输入&#xff1a;图像输入或者文字输入 算法&#xff1a;还是基础的模块计算 神经网络中的参数几千…

[JavaScript] 动态获取方法参数名

JavaScript&#xff08;简称“JS”&#xff09;是一种具有函数优先的轻量级&#xff0c;解释型或即时编译型的编程语言。虽然它是作为开发Web页面的脚本语言而出名&#xff0c;但是它也被用到了很多非浏览器环境中&#xff0c;JavaScript基于原型编程、多范式的动态脚本语言&am…

Java导出Excel给每一列设置不同样式示例

Excel导出这里不讲&#xff0c;方法很多&#xff0c;原生的POI可以参照 Java原生POI实现的Excel导入导出&#xff08;简单易懂&#xff09; 这里只说怎么给Excel每一列设置不同的样式&#xff0c;比如下面这样的 直接上代码 Overridepublic void exportTemplate(HttpServletRe…

昇思25天学习打卡营第23天|CV-ResNet50迁移学习

打卡 目录 打卡 迁移学习 实战练习 数据准备 数据处理 数据处理函数 数据处理流程 数据可视化 训练模型 构建Resnet50网络 固定特征进行训练 network 的输出 训练和评估 可视化模型预测 通过本文&#xff0c;了解迁移学习的重点在于&#xff0c;了解你的模型结构…

LGA-4500激光气体分析仪说明手册

目 录 阅 读 说 明 I 用户须知 I 概况 I 注意和警示信息 I 供货和运输 III 质保和维修 III 联系方式 III 一、简介 1 1.1概要 1 1.2测量原理 1 1.2.1单线光谱技术 1 1.2.2激光频率扫描技术 2 1.2.3谱线展宽自动修正技术 2 1.3系统组成 2 1.4系统特点 3 1.5系统指标 4 1.6激光产…

决策树可解释性分析

决策树可解释性分析 决策树是一种广泛使用的机器学习算法&#xff0c;以其直观的结构和可解释性而闻名。在许多应用场景中&#xff0c;尤其是金融、医疗等领域&#xff0c;模型的可解释性至关重要。本文将从决策路径、节点信息、特征重要性等多个方面分析决策树的可解释性&…

Thymeleaf(看这一篇就够了)

目录&#xff1a; Thymeleaf变量输出操作字符串&时间条件判断迭代遍历使用状态变量获取域中的数据URL写法相关配置 Thymeleaf Thymeleaf是一款用于渲染XML/HTML5内容的模板引擎&#xff0c;类似JSP。它可以轻易的与SpringMVC等Web框架进行集成作为Web应用的模板引擎。Spri…

暄桐林曦老师推荐书单——《菜根谭》

暄桐是一间传统美学教育教室&#xff0c;创办于2011年&#xff0c;林曦是创办人和授课老师&#xff0c;教授以书法为主的传统文化和技艺&#xff0c;皆在以书法为起点&#xff0c;亲近中国传统之美&#xff0c;以实践和所得&#xff0c;滋养当下生活。      在暄桐教室的课…

机械运动、工控机概念整理

Signal &#xff1a; 信号 pul 【pulse】是驱动脉冲信号&#xff0c;发一个脉冲&#xff0c;电机走一步。 dir是方向控制信号&#xff0c;控制电机正转或反转。 ena是使能信号&#xff0c;这个信号必须开启&#xff0c;才能驱动电机。 voltage&#xff1a; 电压 VCC&#…

Python软件开发:AI毕业设计生成器引领未来

&#x1f31f; 革新软件开发&#xff1a;Python毕业设计生成器引领未来 &#x1f680; 目录 &#x1f31f; 革新软件开发&#xff1a;Python毕业设计生成器引领未来 &#x1f680;&#x1f393; 课题简介&#x1f31f; 开发目的&#x1f4c8; 开发意义 &#x1f4da; 研究方法&…

[ BLE4.0 ] 伦茨ST17H66开发-串口UART0的接收与发送

目录 一、前言 二、实现步骤 1.设置回调函数 2.关闭睡眠模式 三、效果展示 四、工程源代码 一、前言 串口通信在任何一款单片机开发中都是尤为重要的。本文涉及的开发所使用的例程依然是基于[ BLE4.0 ] 伦茨ST17H66开发-OSAL系统中添加自己的Task任务文章的工程源码&#x…

进程间通信--套接字socket

前面提到的管道、消息队列、共享内存、信号和信号量都是在同一台主机上进行进程间通信&#xff0c;那要想跨网络与不同主机上的进程之间通信&#xff0c;就需要Socket通信了。 实际上&#xff0c;Socket通信不仅可以跨网络与不同主机的进程间通信&#xff0c;还可以在同主机上…

一键升级GIS场景视觉效果,告别繁琐操作

在当今的数字化时代&#xff0c;GIS&#xff08;地理信息系统&#xff09;不再仅仅只能通过一些二维示意图或简陋的三维地形图表示&#xff0c;它可以通过专业的软件简单升级视效。想象一下&#xff0c;在你的GIS场景中&#xff0c;阳光明媚的天气、突如其来的暴风雨、缭绕的晨…

工时管理平台核心功能解析:你需要了解的

国内外主流的10款工时管理平台对比&#xff1a;PingCode、Worktile、Todoist、ClickUp、滴答清单、专注清单、一木清单、NarTick、Tweek、朝暮计划。 在选择合适的工时管理平台时&#xff0c;你是否感到挑战重重&#xff1f;市场上的各种选项似乎都声称能够提升效率和减轻管理负…

【SQL Server点滴积累】SQL Server 2016数据库邮件(Database Mail)功能故障的解决方法

今天和大家分享SQL Server 2016数据库邮件(Database Mail)功能故障的解决方法 故障现象&#xff1a; 在SQL Server 2016中配置完成数据库邮件(Database Mail)功能后&#xff0c;当你尝试发送测试邮件后&#xff0c;既收不到测试邮件&#xff0c;也不显示错误消息 KB3186435 -…

Python数值计算(11)——拉格朗日插值

本篇介绍一下多项式插值中&#xff0c;拉格朗日法的原理及其实现。 1. 一点数学知识 先引用数学背景。如果给定N个点&#xff0c;然后要求一个多项式通过这N个点&#xff0c;最简单直接的方式是列出线性方程求解&#xff0c;N个点可以确定N个未知量&#xff0c;则所求的拟合多…

下面关于枚举的描述正确的一项是?

A. 枚举中定义的每一个枚举项其类型都是String&#xff1b; B. 在Java中可以直接继承java.util.Enum类实现枚举类的定义&#xff1b; C. 利用枚举类中的values()方法可以取得全部的枚举项&#xff1b; D. 枚举中定义的构造方法只能够使用private权限声明&#xff1b; 答案选择…

springboot山东外事职业大学校园食堂点餐系统-计算机毕业设计源码10417

摘 要 近年来&#xff0c;随着国民收入的提高&#xff0c;各行业取得长足进步&#xff0c;也带动了互联网行业的快速发展&#xff0c;许多传统行业开始与互联网相结合&#xff0c;通过数字化转型打造新的发展生态。 本文针对山东外事大学校园食堂点餐系统的需求&#xff0c;基于…