Linux进程通信——消息队列

概念

消息队列,是消息的链接表,存放在内核中。一个消息队列由一个标识符(即队列ID)来标识。

特点

1.消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级。(消息队列是结构体)
2.消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除
3.消息队列可以实现消息的随机查询,消息不一定要以先进先出的次席读取,也可以按消息的类型读取

两者的队列ID需相同才能成功实现存放数据和取数据,如图都指向队列1的最后一个。

消息队列与管道的不同点:写入读取后内容还存在于Linux内核中,不会跟管道一样读取完就消失。

创建

从消息队列特点可知,两个进程分别需要同队列ID相同的队列进行写入数据并读取数据,此时要想成功创建一个消息队列,需关心两个问题:

问题一:进程B如何添加消息到队列

问题二:进程A如何读取队列的消息

头文件

#include <sys/msg.h>

常用API

msgget()

创建或打开消息队列:成功返回队列ID,失败返回-1

int msgget(key_t key, int flag);
key是一个索引值,为非负数,将通过索引值在Linux内核找到队列
flag打开队列的方式

在以下两种情况下,msgget将创建一个新的消息队列:
1、如果没有与键值key相对应的消息队列,并且flag中包含了IPC_CREAT标志位。

msgget(key,IPC_CREAT);

2、key参数为IPC_PRIVATE

msgget(key,IPC_PRIVATE);

msgsnd()

添加消息:成功返回0,失败返回-1

int msgsnd(int msqid, const void *ptr, size_t size, int flag);

msqid:消息队列的ID
ptr:写入的数据,指向消息缓冲区的指针,此位置用来暂时存储发送和接收的消息,是一个用户可定义的通用结构,形态如下:

struct msgbuf
{
    long mtype; //消息类型,必须大于0
    char mtext[1];//消息文本 
};

size:数据的长度
flag:0,表示忽略,表示进程将被阻塞直到函数可以从队列中得到符合条件的消息为止;(还有许多,此处省略)

msgrcv()

读取消息:成功返回消息数据的长度,失败返回-1

int msgrcv(int msqid, void *ptr, size_t size, long type,int flag);

msqid:消息队列的ID
ptr:写入的数据,指向消息缓冲区的指针,此位置用来暂时存储发送和接收的消息,是一个用户可定义的通用结构,形态如下:

struct msgbuf
{
    long mtype; //消息类型,必须大于0
    char mtext[1];//消息文本 
};

type:消息类型

type = 0返回队列中的第一个消息
type >0返回队列中消息类型为 type 的第一个消息
type< 0返回队列中消息类型值小于或等于 type 绝对值的消息,如果有多个,则取类型值最小的消息

可以看出,type值非 0 时用于以非先进先出次序读消息。也可以把 type 看做优先级的权值。

size:数据的长度

flag:0,表示忽略,表示进程将被阻塞直到函数可以从队列中得到符合条件的消息为止;(还有许多,此处省略)

代码展示

get.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

struct msgbuf
{
	long mtype;
    char mtext[128];
};


int main()
{
	int msgId;//创建消息队列ID
	struct msgbuf readBuf;//定义一个读取数据的结构体

	msgId = msgget(1234,IPC_CREAT|0777);//在内核中打开或建立键值为1234的,权限为0777的消息队列
	if(msgId == -1)//如果创建失败则执行下面代码
	{
		printf("create queue failed\n");
	}

	msgrcv(msgId,&readBuf,sizeof(readBuf.mtext),888,0);//从队列中获取888类型的数据并存放到结构体的mtext中,如果队列中未出现888类型的数据,则程序阻塞在这里,这里的888需要与写入队列类型数据一致
	printf("read from queue:%s\n",readBuf.mtext);

	struct msgbuf sendBuf = {999,"thank you for reach\n"};//读取完毕后将字符串内容写入到999类型的数据中,这里的999类型需要与读取的类型数据一致
	msgsnd(msgId,&sendBuf,strlen(sendBuf.mtext),0);//将上一行的结构体数据写入1234消息队列中
	
	return 0;
}

send.c

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>

struct msgbuf
{
	long mtype;
    char mtext[128];
};


int main()
{
	int msgId;
	struct msgbuf sendBuf = {888,"this is message from queue\n"};//将字符串内容写入到888类型的数据中,这里的888类型需要与读取的类型数据一致
    struct msgbuf readBuf;

	msgId = msgget(1234,IPC_CREAT|0777);
	if(msgId == -1)
	{
		printf("create queue failed\n");
	}

	msgsnd(msgId,&sendBuf,strlen(sendBuf.mtext),0);//将结构体内容写入到1234消息队列中

	msgrcv(msgId,&readBuf,sizeof(readBuf.mtext),999,0);//写入之后从队列中获取999类型的数据并存放到结构体的mtext中,如果队列中未出现999类型的数据,则程序阻塞在这里,这里的999需要与写入队列类型数据一致
	printf("return form queue:%s\n",readBuf.mtext);
	
	return 0;
}

运行get.c,创建并打开键值为1234的消息队列,但此时表现为堵塞状态,因为队列里没有888类型的数据

运行send.c,创建并打开键值为1234的消息队列,往队列里写入888类型的数据,此时接收端会接受到写入端写入消息队列的数据并将其读取,同时让接收端往队列里写入999类型的数据,让写入段接受999类型的数据并读取

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电力工作记录仪、智能安全帽、智能布控球助力智能电网建设

电力行业的建设和发展是国家经济发展的重要支撑&#xff0c;而智能电网作为电力系统的重要组成部分&#xff0c;它的安全高效运行关乎到整个电力系统乃至民生的稳定和安全。为了加快国家经济的发展以及满足人们对电力的需求和用电可靠性的要求&#xff0c;国家早在十二规划中就…

python2环境问题

pip源推荐使用 -i http://pypi.tuna.tsinghua.edu.cn/simple --trusted-host pypi.tuna.tsinghua.edu.cn 安装pip工具&#xff0c;可以环境上已有的pip赋值到对应目录下 更新pip工具&#xff0c;python2的pip需要20.3版本以前的。解决pip命令从其它环境复制过来导致的一系列…

python查找算法_顺序查找

顺序查找&#xff08;Sequential Search&#xff09;是一种简单直观的搜索算法&#xff0c;用于在无序数组中查找特定元素。它的基本思想是逐个遍历数组中的元素&#xff0c;直到找到目标元素或遍历完整个数组。本文将介绍顺序查找的基本原理&#xff0c;并通过Python代码进行详…

基于晶体结构算法优化概率神经网络PNN的分类预测 - 附代码

基于晶体结构算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于晶体结构算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于晶体结构优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…

听GPT 讲Rust源代码--src/librustdoc(2)

题图来自 Chromium项目将支持Rust编程语言[1] File: rust/src/librustdoc/html/render/search_index.rs 在Rust源代码中&#xff0c;rust/src/librustdoc/html/render/search_index.rs文件的作用是生成搜索索引&#xff0c;用于在Rust文档页面上进行关键字搜索。该文件实现了一…

原来 TinyVue 组件库跨框架(Vue2、Vue3、React、Solid)是这样实现的?

本文由 TinyVue 组件库核心成员郑志超分享&#xff0c;首先分享了实现跨框架组件库的必要性&#xff0c;同时通过演示Demo和实际操作向我们介绍了如何实现一个跨框架的组件库。 前言 前端组件库跨框架是什么&#xff1f; 前端组件库跨框架是指在不同的前端框架&#xff08;如…

【实战详解】如何快速搭建接口自动化测试框架?Python + Requests

摘要&#xff1a; 本文主要介绍如何使用Python语言和Requests库进行接口自动化测试&#xff0c;并提供详细的代码示例和操作步骤。希望能对读者有所启发和帮助。 前言 随着移动互联网的快速发展&#xff0c;越来越多的应用程序采用Web API&#xff08;也称为RESTful API&#…

2023年G3锅炉水处理证考试题库及G3锅炉水处理试题解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2023年G3锅炉水处理证考试题库及G3锅炉水处理试题解析是安全生产模拟考试一点通结合&#xff08;安监局&#xff09;特种作业人员操作证考试大纲和&#xff08;质检局&#xff09;特种设备作业人员上岗证考试大纲随机…

C++函数

转载知呼大佬06 - C函数 - 知乎 (zhihu.com) 06 - C函数 本期我们讨论的是 C 中的函数。 函数到底是什么呢&#xff0c;函数就是我们写的代码块&#xff0c;被设计用来执行特定的任务&#xff0c;以后我们学习 class 类的时候&#xff0c;这些块会被称为方法&#xff0c;但是…

【计算机网络学习之路】Windows下的socket编程

文章目录 前言Windows下的socket编程1.预备工作2. socket编程 结束语 前言 本系列文章是计算机网络学习的笔记&#xff0c;欢迎大佬们阅读&#xff0c;纠错&#xff0c;分享相关知识。希望可以与你共同进步。 本篇文章仅记录Windows下socket编程和Linux的不同&#xff0c;并没…

Maven工程继承关系,多个模块要使用同一个框架,它们应该是同一个版本,项目中使用的框架版本需要统一管理。

1、父工程pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/PO…

红队攻防之Goby反杀

若结局非我所愿&#xff0c;那就在尘埃落定前奋力一搏。 本文首发于先知社区&#xff0c;原创作者即是本人 一、弹xss 为了方便&#xff0c;本次直接使用 PhpStudy 进行建站&#xff0c;开启的web服务要为MySQLNginx&#xff0c;这里的 PhpStudy 地址为 http://x.x.x.x&…

树与二叉树堆:二叉树

二叉树的概念&#xff1a; 二叉树是树的一种&#xff0c;二叉树是一个节点&#xff0c;最多只有两个子节点&#xff0c;二叉树是一个特殊的树二叉树的度最大为2 从上图可得一棵二叉树是结点的一个有限集合&#xff0c;该集合: 或者为空由一个根结点加上两棵别称为左子树和右子…

ECharts零基础使用思路 图表案例网站推荐

1、用npm安装echarts npm i echarts -S 2、引入 &#xff08;1&#xff09;可以在mian.js里全局引入 import echarts from ‘echarts’ Vue.prototype.$echarts echarts 将echarts挂载在Vue原型上 用时直接this.$echarts即可 &#xff08;2&#xff09;也可以在组件中按需引入…

〖大前端 - 基础入门三大核心之JS篇㊵〗- DOM事件监听及onxxx的使用

说明&#xff1a;该文属于 大前端全栈架构白宝书专栏&#xff0c;目前阶段免费&#xff0c;如需要项目实战或者是体系化资源&#xff0c;文末名片加V&#xff01;作者&#xff1a;不渴望力量的哈士奇(哈哥)&#xff0c;十余年工作经验, 从事过全栈研发、产品经理等工作&#xf…

windows电脑连接Android和iPhone真机调试

windows电脑连接Android和iPhone真机调试 目前用的是Hbuilder X编辑器&#xff0c;在正常情况下&#xff0c;Android手机需要在 "设置 ----> 更多设置 ----->关于手机 ------> 版本号&#xff08;手指点击5-7下即可打开开发者模式&#xff09;"(我的是vivo的…

人工智能基础_机器学习046_OVR模型多分类器的使用_逻辑回归OVR建模与概率预测---人工智能工作笔记0086

首先我们来看一下什么是OVR分类.我们知道sigmoid函数可以用来进行二分类,那么多分类怎么实现呢?其中一个方法就是使用OVR进行把多分类转换成二分类进行计算. OVR,全称One-vs-Rest,是一种将多分类问题转化为多个二分类子问题的策略。在这种策略中,多分类问题被分解为若干个二…

小诺2.0开源版工程启动

小诺是一款开源的前后端开发框架&#xff0c;同若依、SpringBladex一样可作为私活、外包脚手架。 开源地址&#xff1a;Snowy: 最新&#xff1a;&#x1f496;国内首个国密前后分离快速开发平台&#x1f496;&#xff0c;采用Vue3AntDesignVue3 ViteSpringBootMpHuToolSaToke…

计算机基础知识56

choices参数的使用 # 应用场景&#xff1a; 学历&#xff1a;小学、初中、高中、本科、硕士、博士、1 2 3 4 5 6 客户来源: 微信渠道、广告、介绍、QQ、等等 性别&#xff1a;男、女、未知 # 对于以上可能被我们列举完的字段我们一般都是选择使用…

操作系统(三)| 进程管理上 进程状态 同步 互斥

目录 1 进程和程序区别 2 进程状态 2.1 进程的5种基本状态 2.2 进程状态之间转换 2.3 七状态模型 3 进程描述 3.1 进程控制块 PCB 3.2 进程块组织方式 4 进程控制 5 进程同步 互斥 5.1 区分进程互斥和同步 5.2 核心方案 5.3 其他方案 方案1 设置锁变量 方案2 严…