信号通信与消息队列实现的通信:2024/2/23

news2025/2/24 20:43:32

作业1:将信号和消息队列的课堂代码敲一遍

1.1 信号

1.1.1 信号默认、捕获、忽略处理(普通信号)

代码:

#include <myhead.h>
void handler(int signo)
{
	if(signo==SIGINT){
		printf("用户键入 ctrl+c\n");
	}
}
int main(int argc, const char *argv[])
{
	//忽略信号
	if(signal(SIGINT,SIG_IGN)==SIG_ERR){
		perror("signal error");
		return -1;
	}
	/*
	//默认处理信号
	if(signal(SIGINT,SIG_IGN)==SIG_ERR){
		perror("signal error");
		return -1;
	}
	//捕获信号
	if(signal(SIGINT,handler)==SIG_ERR){
		perror("signal error");
		return -1;
	}
	*/
	while(1)
	{
		printf("123456\n");
		sleep(1);
	}
	return 0;
}

效果图:

1.1.2 SIGCHLD回收僵尸进程

代码:

#include <myhead.h>
void handler(int signo)
{
	if(signo==SIGCHLD){
		while(waitpid(-1,NULL,WNOHANG)>0);
		//waitpid(-1,NULL,WNOHANG);
	}
}
int main(int argc, const char *argv[])
{
	
	//捕获信号
	if(signal(SIGCHLD,handler)==SIG_ERR){
		perror("signal error");
		return -1;
	}
	//创建僵尸进程
	for(int i=0;i<5;i++)
	{
		if(fork()==0){
			sleep(1);
			exit(EXIT_SUCCESS);
		}
	}
	while(1);
	return 0;
}

效果图:

1.1.3 模拟出牌

代码:

#include <myhead.h>

//信号处理函数
void handler(int signo)
{
	if(signo==SIGALRM){
		printf("系统为您出了一张牌\n");
		alarm(5);
	}
}
int main(int argc, const char *argv[])
{
	//捕获SIGALRM信号
	if(signal(SIGALRM,handler)==SIG_ERR){
		perror("signal error");
		return -1;
	}
	alarm(5);             //启动定时器
	
	//出的牌
	char ch=0;
	while(1)
	{
		scanf("%c",&ch);
		getchar();

		printf("你出的牌为:%c\n",ch);
		alarm(5);
	}
	return 0;
}

效果图:

1.1.4 发送信号函数

代码:

#include <myhead.h>

void hander(int signo)
{
	if(signo==SIGUSR1){
		printf("大清亡了\n");
		raise(SIGKILL);
	}
}
int main(int argc, const char *argv[])
{
	//发送信号
	if(signal(SIGUSR1,hander)==SIG_ERR){
		perror("signal error");
		return -1;
	}
	
	
	//创建进程
	pid_t pid=fork();

	if(pid>0){
		//父进程
		while(1)
		{
			printf("这是朕的江山\n");
			sleep(1);
		}
	}else if(pid==0){
		//子进程
		sleep(3);
		printf("我才是真命天子\n");
		kill(getppid(),SIGUSR1);
		while(1)
		{
			printf("现在是我的了\n");
			sleep(1);
		}
	}else{
		perror("pid error");
		return -1;
	}
	return 0;
}

效果图:

1.2 消息队列

msgsnd.c:

#include <myhead.h>

//消息队列结构体
struct msgbuf
{
	long mtype;
	char mtest[1024];
};
//宏表示消息正文的大小
#define MSGSIZE sizeof(struct msgbuf)-sizeof(long)

int main(int argc, const char *argv[])
{
	//创建 key 值
	key_t key=0;
	if((key=ftok("/",'k'))==-1){
		perror("ftok error");
		return -1;
	}
	printf("fork success key=%#x\n",key);
	//根据key值创建消息队列
	int msqid=-1;
	if((msqid=msgget(key,IPC_CREAT|0664))==-1){
		perror("msgget error");
		return -1;
	}
	printf("msgget success msqid=%#x\n",msqid);
	//定义一个消息
	struct msgbuf sbuf;

	while(1)
	{
		//清空正文的容器
		bzero(sbuf.mtest,sizeof(sbuf.mtest));
		
		printf("请输入当前消息的类型:");
		scanf("%ld",&sbuf.mtype);
		getchar();                 //吸收垃圾字符
		printf("请输入消息正文:");
		fgets(sbuf.mtest,sizeof(sbuf.mtest),stdin);
		sbuf.mtest[strlen(sbuf.mtest)-1]='\0';

		//将消息存放到队列中
		msgsnd(msqid,&sbuf,MSGSIZE,0);
		printf("发送成功\n");

		if(strcmp(sbuf.mtest,"quit")==0){
			break;
		}

	}

	return 0;
}

msgrcv.c:

#include <myhead.h>

//消息队列结构体
struct msgbuf
{
	long mtype;
	char mtest[1024];
};
//宏表示消息正文的大小
#define MSGSIZE sizeof(struct msgbuf)-sizeof(long)

int main(int argc, const char *argv[])
{
	//创建 key 值
	key_t key=0;
	if((key=ftok("/",'k'))==-1){
		perror("ftok error");
		return -1;
	}
	printf("fork success key=%#x\n",key);
	//根据key值创建消息队列
	int msqid=-1;
	if((msqid=msgget(key,IPC_CREAT|0664))==-1){
		perror("msgget error");
		return -1;
	}
	printf("msgget success msqid=%#x\n",msqid);
	//定义一个消息
	struct msgbuf rbuf;

	while(1)
	{
		//清空正文的容器
		bzero(rbuf.mtest,sizeof(rbuf.mtest));
	
		//从消息队列中读取一个消息
		msgrcv(msqid,&rbuf,MSGSIZE,0,0);

		printf("收到的消息为:%s\n",rbuf.mtest);

		if(strcmp(rbuf.mtest,"quit")==0){
			break;
		}

	}

	//删除消息队列
	if(msgctl(msqid,IPC_RMID,NULL)!=0){
		perror("msgctl error");
		return -1;
	}

	return 0;
}

效果图:

作业2:使用消息队列完成两个进程间相互通信

msgsnd.c:

#include <myhead.h>

//定义一个消息类型
struct msgbuf
{
	long mtype;
	char mtest[1024];
};

//宏表示消息正文大小
#define MSGSIZE sizeof(struct msgbuf)-sizeof(long)

/*****************************主程序***********************/
int main(int argc, const char *argv[])
{
	//1、创建key值
	key_t key=0;
	if((key=ftok("/",'k'))==-1){
		perror("ftok error");
		return -1;
	}
	//根据key值创建一个消息队列
	int msqid=-1;
	if((msqid=msgget(key,IPC_CREAT|0664))==-1){
		perror("msgget error");
		return -1;
	}
	//创建一个子进程
	pid_t pid=fork();

	if(pid>0){
		//父进程向消息队列中写入类型为1的消息正文
		//定义一个消息
		struct msgbuf sbuf;
		sbuf.mtype=1;
		while(1)
		{
			//清空容器
			bzero(sbuf.mtest,sizeof(sbuf.mtest));

			printf("发送的消息:");
			fgets(sbuf.mtest,sizeof(sbuf.mtest),stdin);
			sbuf.mtest[strlen(sbuf.mtest)-1]='\0';

			//将消息存放到消息队列
			msgsnd(msqid,&sbuf,MSGSIZE,0);
			printf("发送成功\n");

			if(strcmp(sbuf.mtest,"quit")==0){
				break;
			}
		}
        wait(NULL);	
	}else if(pid==0){
		//子进程从消息队列中取出类型为2的消息正文
		//定义一个消息
		struct msgbuf rbuf;

		while(1)
		{
			//清空容器
			bzero(rbuf.mtest,sizeof(rbuf.mtest));

			//从消息队列中读取类型为2的消息正文
			msgrcv(msqid,&rbuf,MSGSIZE,2,0);

			printf("收到的消息为:%s\n",rbuf.mtest);
			if(strcmp(rbuf.mtest,"quit")==0){
				break;
			}
		}
        exit(EXIT_SUCCESS);
	}else{
		perror("fork error");
		return -1;
	}

	return 0;
}

msgrcv.c:

#include <myhead.h>

//定义一个消息类型
struct msgbuf
{
	long mtype;
	char mtest[1024];
};

//宏表示消息正文大小
#define MSGSIZE sizeof(struct msgbuf)-sizeof(long)

/*****************************主程序***********************/
int main(int argc, const char *argv[])
{
	//1、创建key值
	key_t key=0;
	if((key=ftok("/",'k'))==-1){
		perror("ftok error");
		return -1;
	}
	//根据key值创建一个消息队列
	int msqid=-1;
	if((msqid=msgget(key,IPC_CREAT|0664))==-1){
		perror("msgget error");
		return -1;
	}
	//创建一个子进程
	pid_t pid=fork();

	if(pid>0){
		//父进程从消息队列中取出类型为1的消息正文
		//定义一个消息
		struct msgbuf rbuf;

		while(1)
		{
			//清空容器
			bzero(rbuf.mtest,sizeof(rbuf.mtest));

			//从消息队列中读取类型为1的消息正文
			msgrcv(msqid,&rbuf,MSGSIZE,1,0);

			printf("收到的消息为:%s\n",rbuf.mtest);
			if(strcmp(rbuf.mtest,"quit")==0){
				break;
			}
		}
        wait(NULL);
	}else if(pid==0){
		//子进程向消息队列中写入类型为2的消息正文
		//定义一个消息
		struct msgbuf sbuf;
		sbuf.mtype=2;
		while(1)
		{
			//清空容器
			bzero(sbuf.mtest,sizeof(sbuf.mtest));

			printf("发送的消息:");
			fgets(sbuf.mtest,sizeof(sbuf.mtest),stdin);
			sbuf.mtest[strlen(sbuf.mtest)-1]='\0';

			//将消息存放到消息队列
			msgsnd(msqid,&sbuf,MSGSIZE,0);
			printf("发送成功\n");

			if(strcmp(sbuf.mtest,"quit")==0){
				break;
			}
		}
        exit(EXIT_SUCCESS);
	}else{
		perror("fork error");
		return -1;
	}

	return 0;
}

效果图:

作业3:思维导图

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

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

相关文章

WebDriver-自动化测试利器剖析

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

C++——STL之map和set

C——STL之map和set &#x1f3d0;序列式容器和关联式容器&#x1f3c0;什么是键值对 &#x1f3d0;什么是set&#x1f3c0;erase&#x1f3c0;count&#x1f3c0;lower_bound&&upper_bound&#x1f3c0;equal_range &#x1f3d0;multipleset&#x1f3d0;什么是map&a…

【办公类-16-10-01】“2023下学期 中4班 自主游戏观察记录(python 排班表系列)

背景需求 上学期的周安排里&#xff0c;每班每周的自主游戏会轮到多个不同的内容 因此在每周的自主游戏观察有2次记录&#xff0c;观察的项目可以写不一样的&#xff0c; 如一位老师写沙水游戏&#xff0c;另一位写表演游戏 本学期&#xff0c;中班的自主游戏全部是户外的&am…

[算法沉淀记录] 排序算法 —— 归并排序

排序算法 —— 归并排序 算法介绍 归并排序是一种分治算法&#xff0c;由约翰冯诺伊曼在1945年发明。它的工作原理是将未排序的列表划分为n个子列表&#xff0c;每个子列表包含一个元素(包含一个元素的列表被认为是有序的)&#xff0c;然后重复合并子列表以生成新的有序子列表…

​LeetCode解法汇总2583. 二叉树中的第 K 大层和

目录链接&#xff1a; 力扣编程题-解法汇总_分享记录-CSDN博客 GitHub同步刷题项目&#xff1a; https://github.com/September26/java-algorithms 原题链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 描述&#xff1a; 给你一棵二叉树的根节点 root 和一个正整…

Redis进阶篇

Redis线程模型 redis是基于内存运行的高性能k-v数据库&#xff0c;6.x之前是单线程, 对外提供的键值存储服务的主要流程 是单线程&#xff0c;也就是网络 IO 和数据读写是由单个线程来完成&#xff0c;6.x之后引入多线程而键值对读写命 令仍然是单线程处理的&#xff0c;所以 …

有趣且重要的JS知识合集(19)前端实现图片的本地上传/截取/导出

input[file]太丑了&#xff0c;又不想去改button样式&#xff0c;那就自己实现一个上传按钮的div&#xff0c;然后点击此按钮时&#xff0c;去触发file上传的事件, 以下就是 原生js实现图片前端上传 并且按照最佳宽高比例展示图片&#xff0c;然后可以自定义截取图片&#xff0…

Cesium入门基础一:cesium加载地球与环境搭建

一、cesium加载地球与环境搭建 1、搭建vue3项目 使用vite进行搭建。 npm init vitelatest根据操作提示选择&#xff1a;vue 3 Typescript 2、下载cesium库 终端输入&#xff1a; npm install cesium3、创建cesium地图容器 <template><div id"view_contai…

C 标准库 - <errno.h>

在C语言编程中&#xff0c;<errno.h> 头文件扮演着至关重要的角色&#xff0c;它提供了一个全局变量 errno 以及一系列预定义宏&#xff0c;用于指示系统调用或库函数执行过程中发生的错误。这些宏有助于程序员诊断和处理运行时错误。 errno 变量 extern int errno;err…

【文件搜索项目】使用jdbc操作SQLite

一. 插入&#xff08;采用变量的方式插入&#xff09; 1.创建数据源.DateSource 2.建立连接 3.构造SQL语句 4.执行SQL语句 5.释放资源 public class TestSQLite {public static void main(String[] args) throws SQLException {textInsert();}public static void textInsert(…

IO进程线程的通信操作

1.编程实现互斥机制 程序代码&#xff1a; 1 #include<myhead.h>2 int num520;//临界资源3 //1.创建一个互斥锁变量4 pthread_mutex_t mutex;//定义一个pthread_mutex_t类型的变量5 //定义任务1函数6 void *task1(void *arg)7 {8 printf("不畏过去\n");9 …

【前端素材】推荐优质后台管理系统GramOs平台模板(附源码)

一、需求分析 后台管理系统是一种用于管理网站、应用程序或系统的工具&#xff0c;它通常作为一个独立的后台界面存在&#xff0c;供管理员或特定用户使用。下面详细分析后台管理系统的定义和功能&#xff1a; 1. 定义 后台管理系统是一个用于管理和控制网站、应用程序或系统…

git切换仓库地址

已有git仓库&#xff0c;要切换提交的仓库地址&#xff0c;用以下命令 git remote set-url origin 自己的仓库地址 用以下命令&#xff0c;查看当前仓库地址&#xff1a; git remote show origin 切换仓库后&#xff0c;用以下命令初始化提交仓库&#xff1a; git push -u o…

cocos creator3.x项目打包成aar 加入到已有的Android工程

Cocos crearor版本&#xff1a; 3.4.2 Android Studio Flamingo | 2022.2.1 Patch 2 1、配置构建安卓项目 2、 运行编译无报错 出现问题可尝试修改Gradle版本 修改jdk版本 3、对libservice打包成aar 打包完后 再build/outputs找到aar 如果看不到Tasks模块&#xff0c;在Fil…

连接查询(学习笔记)

通过对DQL的学习&#xff0c;我们可以很轻松的从一张数据表中查询出需要的数据&#xff1b;在企业的应用开发中&#xff0c;我们经常需要从多张表中查询数据&#xff08;例如&#xff1a;我们查询学生信息的时候需要同时查询学生的班级信息&#xff09;&#xff0c;可以通过连接…

【Spring】IoC容器 控制反转 与 DI依赖注入 概念 第一期

文章目录 Spring 和 SpringFramework概念一、Spring IoC容器 核心概念1.1 组件和组件管理概念1.2 Spring IoC容器和容器实现1.2.1 普通和复杂容器1.2.2 SpringIoC容器介绍1.2.3 SpringIoC容器具体接口和实现类1.2.4 SpringIoC容器管理配置方式 1.3 Spring IoC / DI概念总结二、…

Electron实战之环境搭建

工欲善其事必先利其器&#xff0c;在进行实战开发的时候&#xff0c;我们最终的步骤是搞好一个舒服的开发环境&#xff0c;目前支持 Vue 的 Electron 工程化工具主要有 electron-vue、Vue CLI Plugin Electron Builder、electron-vite。 接下来我们将分别介绍基于 Vue CLI Plu…

DataDreamer:让创建自定义数据集轻松无比!还自带标注!

编辑&#xff1a;OAK中国 首发&#xff1a;oakchina.cn 喜欢的话&#xff0c;请多多&#x1f44d;⭐️✍ 内容可能会不定期更新&#xff0c;官网内容都是最新的&#xff0c;请查看首发地址链接。 ▌前言 Hello&#xff0c;大家好&#xff0c;这里是OAK中国&#xff0c;我是Ash…

数字信号处理:傅里叶分析

本文主要参考视频如下&#xff1a; 数字信号处理9-1_线性时不变系统对复指数信号的响应_哔哩哔哩_bilibili 傅里叶分析的主要研究内容如下所示&#xff1a; 注意&#xff0c;计算机中使用的离散傅里叶变换并不是离散时间傅里叶变换&#xff1b; 前四种都是理论上的变换方式&…

Graphpad Prism10.2.0(329) 安装教程 (含Win/Mac版)

GraphPad Prism GraphPad Prism是一款非常专业强大的科研医学生物数据处理绘图软件&#xff0c;它可以将科学图形、综合曲线拟合&#xff08;非线性回归&#xff09;、可理解的统计数据、数据组织结合在一起&#xff0c;除了最基本的数据统计分析外&#xff0c;还能自动生成统…