复习 --- 消息队列

news2024/11/18 17:32:56

进程间通信机制(IPC)

简述

IPC:Inter Process Communication

进程和进程之间的用户空间相互独立,但是4G内核空间共享,进程间的通信就是通过这4G的内核空间

分类

传统的进程间通信机制

无名管道(pipe)

有名管道(fifo)

信号(signal)

System V中的IPC对象和IPC的区别

消息队列(message queue)

共享内存(shared memory)

信号灯集(semaphore)

可用于主机传输的通信机制

套接字(socket)

消息队列

概念

在内核内存中创建一个队列,进程需要将数据打包成结点,添加到队尾中,或者从队列中读取结点,可以通过消息类型进行消息分类

特点

需要打包,有特定的格式以及消息类型

按照先进先出原则,但是也可以限制消息类型读取

独立于进程,灯进程结束后,消息队列以及其中的内容不会删除,除非中期操作系统或者手动删除

在Linux系统下,可以通过命令ipcs查看消息队列,通过ipcrm -q msqid删除消息队列

函数

ftok()函数,获得一个Key值用来创建消息队列,通过相同的key值可以访问对应的消息队列

msgget()函数创建一个消息队列获得起id号

msgsnd()发送消息到指定消息队列

msgrcv()获取对应消息队列中对应的消息

msgctl()控制消息队列,常用于删除消息队列

#include<myhead.h>
#include<sys/msg.h>
#include<sys/ipc.h>
struct msgbuf
{
	long mtype;      //消息类型
	char mtext[128]; //消息内容
};

//线程1函数
void *task1(void *arg)
{
	int msqid = *(int *)arg;//获取消息队列id号
	struct msgbuf msbuf;//声明消息结构体
	printf("A:\n\t");
	fflush(stdout);
	while (1)
	{
		msbuf.mtype = 1;//消息类型
		fgets(msbuf.mtext,sizeof(msbuf.mtext),stdin);
		msbuf.mtext[strlen(msbuf.mtext)-1]='\0';
		if(msgsnd(msqid,&msbuf,sizeof(msbuf)-sizeof(long),0) == -1)
		{
			perror("msgsnd");
			return NULL;
		}
		//printf("线程%d:发送成功\n",getpid());
		printf("A:\n\t");
		fflush(stdout);
		if (!strcmp(msbuf.mtext,"quit"))
		{
			system("clear");
			exit(0);
		}
	}
	pthread_exit(NULL);
}

//线程2函数
void *task2(void *arg)
{
	int msqid = *(int *)arg;
	struct msgbuf buf;
	ssize_t num = 0;
	while (1)
	{
		bzero(&buf,sizeof(buf));
		if ((num = msgrcv(msqid,&buf,sizeof(buf.mtext),2,0))<0)
		{
			//perror("msgrcv");
			return NULL;
		}
		printf("\nB:\n\t%s\n",buf.mtext);
		printf("A:\n\t");
		fflush(stdout);

		if (!strcmp(buf.mtext,"quit"))
		{
			msgctl(msqid,IPC_RMID,NULL);
			system("clear");
			exit(0);
		}
	}
	pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
	key_t key = ftok("./",0);
	if (key == -1)
	{
		perror("ftok");
		return -1;/* code */
	}
	umask(0);
	int msqid = msgget(key,IPC_CREAT|0664);
	if (msqid == -1)
	{
		perror("msgget");
		return -1;
	}

	pthread_t tid1,tid2;
	if (pthread_create(&tid1,NULL,task1,&msqid) != 0)
	{
		printf("线程1创建失败\n");
	}
	if (pthread_create(&tid2,NULL,task2,&msqid) != 0)
	{
		printf("线程1创建失败\n");
	}
	

	pthread_join(tid1,NULL);
	pthread_join(tid2,NULL);

	
	return 0;
}
#include<myhead.h>
//#include<sys/msg.h>
//#include<sys/ipc.h>
struct msgbuf
{
	long mtype;      //消息类型
	char mtext[128]; //消息内容
};

//线程1函数
void *task1(void *arg)
{
	int msqid = *(int *)arg;
	struct msgbuf msbuf;
	printf("B:\n\t");
	fflush(stdout);
	while (1)
	{
		msbuf.mtype = 2;
		fgets(msbuf.mtext,sizeof(msbuf.mtext),stdin);
		msbuf.mtext[strlen(msbuf.mtext)-1]='\0';
		if(msgsnd(msqid,&msbuf,sizeof(msbuf)-sizeof(long),0) == -1)
		{
			perror("msgsnd");
			return NULL;
		}
		//printf("线程%d:发送成功\n",getpid());
		printf("B:\n\t");
		fflush(stdout);
		if (!strcmp(msbuf.mtext,"quit"))
		{
			system("clear");
			exit(0);
		}
	}
	pthread_exit(NULL);
}

//线程2函数
void *task2(void *arg)
{
	int msqid = *(int *)arg;
	struct msgbuf buf;
	ssize_t num = 0;
	while (1)
	{
		bzero(&buf,sizeof(buf));
		if ((num = msgrcv(msqid,&buf,sizeof(buf.mtext),1,0))<0)
		{
			//perror("msgrcv");
			return NULL;
		}
		printf("\nA:\n\t%s\n",buf.mtext);
		printf("B:\n\t");
		fflush(stdout);

		if (!strcmp(buf.mtext,"quit"))
		{
			msgctl(msqid,IPC_RMID,NULL);
			system("clear");
			exit(0);
		}
	}
	pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
	key_t key = ftok("./",0);
	if (key == -1)
	{
		perror("ftok");
		return -1;/* code */
	}
	umask(0);
	int msqid = msgget(key,IPC_CREAT|0664);
	if (msqid == -1)
	{
		perror("msgget");
		return -1;
	}

	pthread_t tid1,tid2;
	if (pthread_create(&tid1,NULL,task1,&msqid) != 0)
	{
		printf("线程1创建失败\n");
	}
	if (pthread_create(&tid2,NULL,task2,&msqid) != 0)
	{
		printf("线程1创建失败\n");
	}
	

	pthread_join(tid1,NULL);
	pthread_join(tid2,NULL);

	
	return 0;
}

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

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

相关文章

Linux Vi编辑器基础操作指南

Linux Vi编辑器基础操作指南 Linux中的Vi是一个强大的文本编辑器&#xff0c;虽然它有一些陡峭的学习曲线&#xff0c;但一旦掌握了基本操作&#xff0c;它就变得非常高效。以下是Vi编辑器的一些基本用法&#xff1a; 打开Vi编辑器&#xff1a; vi 文件名退出Vi编辑器&#xff…

[架构之路-232]:操作系统 - 文件系统存储方法汇总

目录 前言&#xff1a; 一、文件系统存储方法基本原理和常见应用案例&#xff1a; 二、Windows FAT文件系统 2.1 概述 三、Linux EXT文件系统 3.1 基本原理 3.2 索引节点表&#xff08;Inode Table&#xff09; 3.2.1 索引节点表层次结构 3.2.2 间接索引表的大小和表项…

@SpringBootApplication剖析

一、前言 在SpringBoot项目中启动类必须加一个注解SpringBootApplication&#xff0c;今天我们来剖析SpringBootApplication这个注解到底做了些什么。 二、SpringBootApplication简单分析 进入SpringBootApplication源代码如下&#xff1a; 可以看出SpringBootApplication是…

【C语言】动态通讯录(超详细)

通讯录是一个可以很好锻炼我们对结构体的使用&#xff0c;加深对结构体的理解&#xff0c;在为以后学习数据结构打下结实的基础 这里我们想设计一个有添加联系人&#xff0c;删除联系人&#xff0c;查找联系人&#xff0c;修改联系人&#xff0c;展示联系人&#xff0c;排序这几…

数据挖掘(3)特征化

从数据分析角度&#xff0c;DM分为两类&#xff0c;描述式数据挖掘&#xff0c;预测式数据挖掘。描述式数据挖掘是以简介概要的方式描述数据&#xff0c;并提供数据的一般性质。预测式数据挖掘分析数据建立模型并试图预测新数据集的行为。 DM的分类&#xff1a; 描述式DM&#…

arm代码

RISC精简指令集 长度和执行周期固定 长度为一条机器指令在计算机占用的内存大小 指令周期为CPU执行一条机器指令所发费的时间(时钟周期由CPU工作频率决定) CISC复杂指令集 其架构一般用于PC端 X86和X64都是负载指令集CPU 更注重指令的功能性 指令周期和长度都不固定 ar…

014-第二代软件开发

第二代软件开发 文章目录 第二代软件开发项目介绍正式开始我们的Debian Qt 软件开发主题色QSS U盘检测QFileSystemWatcher 屏幕键盘LibUSB 使用 总结 关键字&#xff1a; Qt、 Qml、 U盘检测、 屏幕键盘、 LibUSB 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这…

Qt 综合练习小项目--反金币(2/2)

目录 4 选择关卡场景 4.2 背景设置 4.3 创建返回按钮 4.3 返回按钮 4.4 创建选择关卡按钮 4.5 创建翻金币场景 5 翻金币场景 5.1 场景基本设置 5.2 背景设置 5.3 返回按钮 5.4 显示当前关卡 5.5 创建金币背景图片 5.6 创建金币类 5.6.1 创建金币类 MyCoin 5.6.…

GPT系列论文解读:GPT-2

GPT系列 GPT&#xff08;Generative Pre-trained Transformer&#xff09;是一系列基于Transformer架构的预训练语言模型&#xff0c;由OpenAI开发。以下是GPT系列的主要模型&#xff1a; GPT&#xff1a;GPT-1是于2018年发布的第一个版本&#xff0c;它使用了12个Transformer…

JavaEE 网络原理——TCP的工作机制(中篇 三次握手和四次挥手)

文章目录 一、TCP 内部工作机制——连接管理1. 连接(三次握手)(1).有连接和确认应答之间的关系(2). 通过客户端和服务器详细描述三次握手 2. 断开连接(四次挥手)(1)讨论“四次握手”中间步骤的合并问题。(2) 根据简单的 TCP 代码解释断开连接(3) 四次挥手中的两个重要的 TCP 状…

计算机网络-计算机网络体系结构-物理层

目录 一、通信基础 通信方式 传输方式 码元 传输率 *二 准则 2.1奈氏准则(奈奎斯特定理) 2.2香农定理 三、信号的编码和调制 *数字数据->数字信号 数字数据->模拟信号 模拟数据->数字信号 模拟数据->模拟信号 *四、数据交换方式 电路交换 报文交换…

【刷题笔记10.5】LeetCode:排序链表

LeetCode&#xff1a;排序链表 一、题目描述 给你链表的头结点 head &#xff0c;请将其按 升序 排列并返回 排序后的链表 。 二、分析 这题咱们默认要求&#xff1a;空间复杂度为O(1)。所以这把咱们用自底向上的方法实现归并排序&#xff0c;则可以达到O(1) 的空间复杂…

[极客大挑战 2019]FinalSQL - 异或盲注

1、这题的关键是找注入点&#xff0c;如果选择用户名、密码作为输入点就麻烦了 2、注入点&#xff1a;按钮&#xff0c;点击就传id&#xff1b;当id1时&#xff0c;提示Click others   可以利用id的特性&#xff0c;构造异或匹配   payload: f"1^(ord(substr((select…

nodejs+vue中医体质的社区居民健康管理系统elementui

可以实现首页、中医体质量表、健康文章、健康视频、我的等&#xff0c;在我的页面可以对医生、小区单元、医疗药品等功能进行操作。目前主要的健康管理系统是以西医为主&#xff0c;而为了传扬中医文化&#xff0c;提高全民健康意识&#xff0c;解决人民日益增长的美好生活需要…

基于SpringBoot的图书进销存管理系统

目录 前言 一、技术栈 二、系统功能介绍 用户信息管理 图书类型管理 商品退货管理 客户信息管理 图书添加 客户添加 应收金额 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实…

Ubuntu无法引导启动的修复

TLDR&#xff1a;使用Boot-Repair工具。 Boot-Repair Boot-Repair是一个简单的工具&#xff0c;用于修复您在Ubuntu中可能遇到的常见启动问题&#xff0c;例如在安装Windows或其他Linux发行版后无法启动Ubuntu时&#xff0c;或者在安装Ubuntu后无法启动Windows时&#xff0c;…

[CISCN 2019华北Day2]Web1 - 布尔盲注

考点&#xff1a;布尔盲注【注意&#xff0c;sql中的substr初始位置是1不是0】 1、页面提示用id传参&#xff0c;而且我们发现是post传参 2、我们传了id1后提示“Hello, glzjin wants a girlfriend.“ 3、由于这题直接输入查询字符&#xff0c;可以通过字典爆破过滤&#xff0…

深度学习基础之参数量(3)

一般的CNN网络的参数量估计代码 class ResidualBlock(nn.Module):def __init__(self, in_planes, planes, norm_fngroup, stride1):super(ResidualBlock, self).__init__()print(in_planes, planes, norm_fn, stride)self.conv1 nn.Conv2d(in_planes, planes, kernel_size3, …

人机关系不是物理关系也不是数理关系

人机关系是一种复杂的社会技术系统&#xff0c;涉及到人类和机器、环境之间的相互作用和影响。它不仅限于物理接触和数理规律&#xff0c;同时还包括了思维、情感、意愿等方面的交流和互动。在人机关系中&#xff0c;人类作为使用者和机器作为工具&#xff08;将来可能会上升到…

rust入门一:安装 Hello World

环境&#xff1a; window 11 专业版rust 1.72.1 一、下载安装 直接去官网&#xff1a; https://www.rust-lang.org/tools/install 下载完成后如下&#xff1a; 双击运行一步步安装就行。 如果是更新或卸载&#xff0c;在命令行中运行&#xff1a; rustup update&#xff1a…