消息队列,Unix的通信机制之一

news2025/1/22 18:39:31

最简单的消息内存的使用流程

①ftok函数生成键值

②msgget函数创建消息队列

③msgsnd函数往消息队列发送消息

④msgrcv函数从消息队列读取消息

⑤msgctl函数进行删除消息队列

一个消息数据应该由以下一个结构体组成,举个例子

struct mymesg{long int mtype;	//类,消息队列可以控制读取相应类型的数据,这时就不一定是先进先出的顺序了,文章后面会继续介绍char mtext[size_t];	//数据,传递的数据存放在这里面};

1.ftok函数生成键值

每一个消息队列都有一个对应的键值(key)相关联(共享内存、信号量也同样需要)。

所需头文件#include

函数原型 key_t ftok(const char *path ,int id);

    path为一个已存在的路径名

    id为0~255之间的一个数值,代表项目ID,自己取

返回值:成功返回键值(相当于32位的int)。出错返回-1

例如:key_t key = ftok( “/tmp”, 66);

2.msgget函数创建消息队列

所需头文件#include

函数原型 int msgget(key_t key,int flag);

    key为ftok生成的键值

    flag为所需要的操作和权限,可以用来控制创建一个消息队列。

        flag的值为IPC_CREAT:如果不存在key值的消息队列,且权限不为0,则创建消息队列,并返回一个消息队列ID。如果存在,则直接返回消息队列ID。

        flag的值为 IPC_CREAT | IPC_EXCL:如果不存在key值的消息队列,且权限不为0,则创建消息队列,并返回一个消息队列ID。如果存在,则产生错误。

返回值:成功返回消息队列ID;出错返回-1

例如:int id = msgget(key,IPC_CREAT|IPC_EXCL|0666);创建一个权限为0666(所有用户可读可写,具体查询linux权限相关内容)的消息队列,并返回一个整形消息队列ID,如果key值已经存在有消息队列了,则出错返回-1。

     int id = msgget(key,IPC_CREAT|0666);创建一个权限为0666(所有用户可读可写,具体查询linux权限相关内容)的消息队列,并返回一个消息队列ID,如果key值已经存在有消息队列了,则直接返回一个消息队列ID。

3.msgsnd函数往消息队列发送消息

所需头文件#include

函数原型 int msgsnd(int msgid,const void *ptr,size_t nbytes,int flag);

    msgid:为msgget返回的消息队列ID值

    ptr:为消息结构体mymesg指针

    nbytes:为消息结构体mymesg里的字符数组mtext大小,sizeof(mtext)

    flag:值可以为0、IPC_NOWAIT

        为0时,当消息队列满时,msgsnd将会阻塞,直到消息能写进消息队列或者消息队列被删除。

        为IPC_NOWAIT时,当消息队列满了,msgsnd函数将不会等待,会立即出错返回EAGAIN

返回值:成功返回0;错误返回-1

例如:msgsnd(id,(void *)&ckxmsg,512,0);

4.msgrcv函数从消息队列读取消息

所需头文件#include

函数原型 ssize_t msgrcv(int msgid,void *ptr,size_t nbytes,long type,int flag);

    msgid:为msgget返回的消息队列ID值

    ptr:为消息结构体mymesg指针

    nbytes:为消息结构体mymesg里的字符数组mtext大小,sizeof(mtext)

    type:在结构体mymesg里我们定义了一个long int mtype,用于分别消息的类型

        type ==0 返回队列中的第一个消息

        type > 0 返回队列中消息类型为type的第一个消息

        type 

    flag:可以为0、IPC_NOWAIT、IPC_EXCEPT

        为0时,阻塞式接收消息,没有该类型的消息msgrcv函数一直阻塞等待

        为IPC_NOWAIT时,如果没有返回条件的消息调用立即返回,此时错误码为ENOMSG

        为IPC_EXCEPT时,与msgtype配合使用返回队列中第一个类型不为msgtype的消息

返回值:成功返回消息数据部分的长度;错误返回-1

例如:msgrcv(id,(void *)&ckxmsg,512,1,0);

5.msgctl函数对消息队列进行控制

简单的操作就是删除消息队列了,也可以获取和改变消息队列的状态

所需头文件#include

函数原型int msgctl(int msgid, int cmd, struct msqid_ds *buf);

    msgid就是msgget函数返回的消息队列ID

    cmd有三个,常用删除消息队列的为IPC_RMID;IPC_STAT:取此队列的msqid_ds结构,并将它存放在buf指向的结构中;IPC_SET:改变消息队列的状态,把buf所指的msqid_ds结构中的uid、gid、mode复制到消息队列的msqid_ds结构内。(内核为每个消息队列维护着一个结构,结构名为msqid_ds,这里就不讲啦,里面存放着消息队列的大小,pid,存放时间等一些参数)

    buf就是结构体msqid_ds

返回值:成功返回0;错误返回-1

例如:msgctl(id,IPC_RMID,NULL);删除id号的消息队列

下面为一个简单的程序,一个service和一个client,service往消息队列里写数据,client从消息队列里读数据,当service输入QUIT时删除消息队列,并且俩程序都退出。

1.service.c

#include
#include
#include
#include
#include
struct mymesg{
	long int mtype;
	char mtext[512];
};
int main()
{
	int id = 0;
	struct mymesg ckxmsg;
	key_t key = ftok("/tmp",66);
	id = msgget(key,IPC_CREAT | 0666);
	if(id == -1)
	{
		printf("create msg error \n");
		return 0;
	}
	while(1)
	{
		char msg[512];
		memset(msg,0,sizeof(msg));
		ckxmsg.mtype = 1;
		printf("input message:");
		fgets(msg,sizeof(msg),stdin);
		strcpy(ckxmsg.mtext,msg);
 
		if(msgsnd(id,(void *)&ckxmsg,512,0) 		{
			printf("send msg error \n");
			return 0;
		}
 
		if(strncmp(msg,"QUIT",4) == 0)
			break;
	}
	if(msgctl(id,IPC_RMID,NULL) 	{
		printf("del msg error \n");
		return 0;
	}
	return 0;
}

2.client.c

 

#include
#include
#include
#include
#include
struct mymesg{
long int mtype;
char mtext[512];
};
int main()
{
int id = 0;
struct mymesg ckxmsg;
key_t key = ftok("/tmp",66);
id = msgget(key,0666|IPC_CREAT);
if(id == -1)
{
printf("open msg error \n");
return 0;
}
while(1)
{
if(msgrcv(id,(void *)&ckxmsg,512,1,0) {
printf("receive msg error \n");
return 0;
}
printf("data:%s\n",ckxmsg.mtext);
if(strncmp(ckxmsg.mtext,"QUIT",4) ==0)
break;
}
return 0;
}

 

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

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

相关文章

教你如何使用eBPF追踪Linux内核

【推荐阅读】 浅析linux内核网络协议栈--linux bridge 深入理解SR-IOV和IO虚拟化 深入linux内核架构--进程&线程 1. 还是先进入内核目录,执行下面的命令,确保内核代码是干净的。 $ make mrproper 2. 执行以下命令,开始对内核进行配…

Feign的性能优化

Feign底层的客户端实现有三种模式 1)URLConnection:默认实现,不支持连接池;(Feign发送http请求时,默认使用的客户端) 2)Apache HttpClient :支持连接池; 3&…

深度学习Week10-YOLOv5-Backbone模块实现(Pytorch)

● 🍨 本文为🔗365天深度学习训练营 中的学习记录博客 ● 🍦 参考文章:Pytorch实战 |第P9周:YOLOv5-Backbone模块实现(训练营内部成员可读) ● 🍖 原作者:K同学啊|接辅导、项目定制 类似于上周内…

也谈特征值和特征向量的几何意义

在当前的大数据分析时代,数据降维是一个重要的分析技术。而谈到数据降维,就离不开一门最为抽象难懂的数学学科分支——线性代数。有人可能会问:一堆向量和矩阵符号的线性代数到底有鸟用?简单地不科学地说,线性代数就是…

【tiktok小店运营小知识】 tiktok小店也会被封吗?有哪些原因呢?

最近开tiktok小店的小伙伴越来越多,运营过程中也会碰到很多问题。有小伙伴问, tiktok小店也会被封吗?有哪些原因呢? tiktok小店也会被封吗?有哪些原因呢? 答案是肯定的。TikTok需要进一步规范店铺经营&…

SRM是什么意思?盘点4个顶级SRM系统

SRM是什么意思?SRM系统,一般指供应商关系管理系统。供应商管理系统是采购管理系统的一个重要模块,强调企业与供应商之间协作共赢。相信在市场动荡的今天,企业与供应商之间的强关联、共命运对于企业来说不失为稳固根基、扩张业务的…

JavaScript系列之ES6默认导出与默认导入

文章の目录一、默认导出二、默认导入三、按需导出四、按需导入五、直接导入并执行模块代码写在最后一、默认导出 语法: export default 默认导出的成员每个模块中,只允许使用唯一的一次 export default,否则会报错! 二、默认导入…

Generative Modeling by Estimating Gradients of the Data Distribution阅读笔记

目录概述传统score-based generative modeling介绍score matchingLangevin dynamics传统score-based generative modeling存在的问题流型假设上的问题低密度区域的问题Noise Conditional Score Network噪声条件分数网络(Noise Conditional Score Networks)annealed Langevin dy…

Kafka 架构、核心机制和场景解读

摘要 Kafka 是一款非常优秀的开源消息引擎,以消息吞吐量高、可动态扩容、可持久化存储、高可用的特性,以及完善的文档和社区支持成为目前最流行的消息队列中间件。 Kafka 的开发社区一直非常活跃,在消息引擎的领域取的不俗成绩之后&#xf…

组装式应用新基建——小程序容器技术

近年来,面对不断变化的业务环境和快速迭代的业务需求,“组装式应用”凭借其灵活性、复用性等优势,成为了重要战略技术趋势。 一直以来,传统应用程序开发面临着诸多挑战:一是没有足够的开发能力;二是选错技…

sql中的!=操作符的天坑(务必警觉)(=在处理null时也是同样有坑)

最近在测试数据,偶尔需要写sql进行数据比对,例如这样的语句: if( column_a ! column_b, 1, 0),万万没想到就是这样的sql语句差点要了我的命。 其实对一般的数据,这条校验语句是没有问题的,最后再筛选一下1的…

Stm32旧版库函数10——A4988 单个步进电机 16拍

#include "stm32f10x_lib.h" #include "motor.h" u8 Step; void GPIO_Key(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin GPIO_Pin_0|GPIO_Pin_1; // 选中管脚9 GPIO_InitStructure.GPIO_Mode …

使用java实现 分布式任务调度平台XXL-JOB 部署及使用

XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。 详细的特性和优点参考官网地址:https://www.xuxueli.com/xxl-job/ 一、任务调度 0.下载官方源…

为什么微服务一定要有网关呢

一、什么是服务网关 服务网关 路由转发 过滤器1、路由转发:接收一切外界请求,转发到后端的微服务上去; 2、过滤器:在服务网关中可以完成一系列的横切功能,例如权限校验、限流以及监控等,这些都可以通过…

Anaconda环境GDAL库基于whl文件的配置方法

本文介绍在Anaconda环境下,基于.whl文件安装Python中高级地理数据处理库GDAL的方法。 在文章Anaconda下Python中GDAL模块的下载与安装方法(https://blog.csdn.net/zhebushibiaoshifu/article/details/124307748)中,我们介绍了基于…

[附源码]计算机毕业设计的实验填报管理系统Springboot程序

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: Springboot mybatis MavenVue等等组成,B/S模式…

我是如何使用docker安装nginx并配置https服务的

文章目录前言一、前期准备1、备案好的域名2、安装nginx2.1 下载nginx的docker镜像2.2 新建用于映射的目录2.3 从容器中拷贝nginx配置2.4 启动 nginx二、配置步骤1、申请免费的证书2、下载证书3、把证书上传至服务器4、配置 .conf 文件4.1 后端接口服务 api.conf 配置4.2 前端项…

数据智仓功能介绍(四)

字段设置 使用场景介绍 字段设置,即在数据智仓中,对输入上一数据处理节点的字段进行显示和隐藏、排序、重命名等操作。 操作配置 对数据类型的转换,主要用户复杂数据的处理的情况下 ,例如某个字段是JSON ,那么通过数…

用 JS 解析 excel 文件需要分几步

八月长江万里晴,千帆一道带风轻。 大家好,我是嘿嘿,今天来聊一聊如何使用 JS 来解析 excel 文件,当然不是直接使用 exceljs、sheetjs 之类的库,那就没意思了,而是主要说一下 JS 解析 excel 表格是如何实现的…

STM32F4 IAP 跳转 APP问题

1. 概念 IAP 的作用,网上其他资料已经有很多介绍了,这里放一个链接,不进行深入的介绍。本文的关注重点是Bootloader在跳转APP程序中出现的问题。 IAP的实现原理讲解以及中断向量表的偏移 2. 程序 本人主要做应用层的开发,所有Boo…