消息队列(IPC技术)

news2025/4/18 0:07:13

目录

一、Linux 中主要的进程间通信方式如下:

二、消息队列函数

(1)msgget函数

功能概述

函数原型

参数解释

返回值

示例

结果

问题

(2) msgsnd函数

功能概述

函数原型

参数说明

返回值

示例

结果

(3)msgrcy函数 

功能概述

函数原型

参数说明

返回值

示例

结果 (与上方的消息队列发送结合)


本篇文章开始前我们先来了解一些基本技术

一、Linux 中主要的进程间通信方式如下:

        管道:包括无名管道和命名管道。无名管道用于具有亲缘关系的进程间单向通信;命名管道可用于不相关进程间的双向通信,通过路径名访问。

        信号:异步通知机制,用于通知进程特定事件发生,进程可自定义信号处理函数或忽略信号。

        共享内存:允许多个进程共享同一块物理内存区域,实现高效的数据交换,需结合信号量等同步机制保证数据一致性。

        消息队列:进程可向队列发送和接收具有特定格式和类型的消息,实现异步、可靠的通信,不同进程可松耦合通信。

        信号量:用于进程间的同步和互斥,通过计数器表示资源可用数量,控制进程对共享资源的访问。

        套接字(socket):网络通信机制,也可用于本地进程间通信,本地通信使用 UNIX 域套接字,提供可靠的双向通信,适用于不同主机或同一主机上不同进程间通信。

注:消息队列、共享内存、信号量数组:生命周期和进程无关,归操作系统直接管理。

二、消息队列函数

(1)msgget函数

功能概述

   msgget 函数的主要功能是创建一个新的消息队列或者获取一个已经存在的消息队列的标识符。消息队列允许不同的进程通过发送和接收消息来进行通信,是一种强大且灵活的进程间通信方式。

函数原型
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgget(key_t key, int msgflg);
参数解释

   key:这是一个用于标识消息队列的id。key 可以是由 ftok 函数生成的键,也可以是特殊值 IPC_PRIVATE

    IPC_PRIVATE:用于创建一个新的、私有的消息队列。这个队列只能由创建它的进程及其子进程访问。

           通过 ftok 生成的键:可以用于多个进程之间共享同一个消息队列。不同的进程使用相同的路径名和项目 ID 调用 ftok 函数,就可以得到相同的 key 值,从而访问同一个消息队列。

    msgflg:这是一个标志位,用于指定消息队列的创建和访问权限。它可以是以下标志的组合。                 

     IPC_CREAT:如果指定的消息队列不存在,则创建一个新的消息队列。

     IPC_EXCL:与 IPC_CREAT 一起使用时,如果消息队列已经存在,则 msgget 调用会失败并返回 -1。权限标志:例如 0666,用于指定消息队列的访问权限,类似于文件的权限设置。

返回值

        成功时,msgget 返回一个非负整数,这个整数就是消息队列的标识符(msgid),后续的 msgsndmsgrcv 等函数将使用这个标识符来操作消息队列。

        失败时,返回 -1,并设置 errno 来指示错误类型。

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

using namespace std;

int main()
{
	// 如果key不存在就创建新的,如果存在就访问这个已经存在的消息队列
	int msgid = msgget((key_t)1001, IPC_CREAT | 0777);
	if (msgid == -1)
	{
		perror("msgget error");
	}

	return 0;
}
结果

问题

        但我们这个有一个问题就是创建了之后就算程序运行结束它也无法消亡我们该怎么办呢。我们使用命令行来查看有哪些方法:

ipcrm -h

第一种办法,使用命令行

ipcrm -Q keyid

第二种办法,直接删除全部

(2) msgsnd函数

功能概述

        msgsnd 是一个在 Unix 和类 Unix 系统中用于消息队列操作的系统调用函数,其主要功能是把消息添加到指定的消息队列里。

函数原型
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
参数说明

   msqid:消息队列的标识符,由 msgget 函数返回。

   msgp:指向消息缓冲区的指针,此缓冲区包含要发送的消息。消息缓冲区的结构通常如下:

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

         msgsz:消息数据部分(mtext)的字节数,但不是结构体长度就是不包含消息类型 mtype

   msgflg:控制函数行为的标志。常见的标志有:

     IPC_NOWAIT:若消息队列已满,函数会立即返回 -1 ,并将 errno 设置为 EAGAIN

       0:若消息队列已满,函数会阻塞,直到有空间可用。

返回值

        若成功,返回 0

        若失败,返回 -1,并设置 errno 来指示错误类型。

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

using namespace std;

typedef struct messagebuf
{
	long mtype;
	char mtext[50];
}MSGBUF;

int main()
{
	// 如果key不存在就创建新的,如果存在就访问这个已经存在的消息队列
	int msgid = msgget((key_t)1001, IPC_CREAT | 0777);
	if (msgid == -1)
	{
		perror("msgget error");
	}
	else
	{
		cout << "msgget success" << endl;

		MSGBUF buf;
		buf.mtype = 1;
		sprintf(buf.mtext, "%s", "hello IPC");

		if (msgsnd(msgid, &buf, sizeof(buf.mtext), 0) < 0)
		{
			perror("msgsnd error");
		}
		else
		{
			cout << "msgsnd success" << endl;
		}
	}

	return 0;
}
结果

(3)msgrcy函数 

注:这是一个阻塞式函数,如果消息队列中没有数据就会阻塞,直到我又发送一个数据到消息队列中才会继续。

功能概述

        它是 Unix 和类 Unix 系统中用于消息队列操作的系统调用,主要功能是从指定的消息队列中接收消息。

函数原型
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
参数说明

        msqid:消息队列的标识符,由 msgget 函数返回。

        msgp:指向消息缓冲区的指针,此缓冲区包含要发送的消息。(与上同)

        msgsz:指定要接收的消息数据部分(mtext)的最大字节数,不包含消息类型 mtype

        msgtyp:指定要接收的消息类型:

      msgtyp == 0:接收消息队列中的第一条消息。

      msgtyp > 0:接收消息类型为 msgtyp 的第一条消息。

      msgtyp < 0:接收消息类型小于或等于 msgtyp 绝对值的最小类型的第一条消息。

        msgflg:控制函数行为的标志,常见的标志有:

      IPC_NOWAIT:如果没有符合条件的消息,函数会立即返回 -1,并将 errno 设置为 ENOMSG

      MSG_EXCEPT(仅在 msgtyp > 0 时有效):接收类型不等于 msgtyp 的第一条消息。

      MSG_NOERROR:如果消息长度超过 msgsz,则截断消息而不产生错误。

返回值

        若成功,返回接收到的消息数据部分(mtext)的字节数。

        若失败,返回 -1,并设置 errno 来指示错误类型。

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

using namespace std;

typedef struct messagebuf
{
	long mtype;
	char mtext[50];
}MSGBUF;

int main()
{
	// 如果key不存在就创建新的,如果存在就访问这个已经存在的消息队列
	int msgid = msgget((key_t)1001, IPC_CREAT | 0777);
	if (msgid == -1)
	{
		perror("msgget error");
	}
	else
	{
		cout << "msgid=" << msgid << endl;

		MSGBUF buf;

		if (msgrcv(msgid, &buf, sizeof(buf.mtext), 1, 0) < 0)
		{
			perror("msgrcv error");
		}
		else
		{
			cout << "从消息队列中接收数据成功,数据为:" << buf.mtext << endl;
		}

	}

	return 0;
}
结果 (与上方的消息队列发送结合)

数据取走之后,字节数又变成0 

 

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

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

相关文章

突破焊丝虚影干扰,端子焊点缺陷检测如何实现自动化?

端子焊点作为 3C 产品中连接电路的关键环节&#xff0c;其质量优劣对产品性能有着决定性影响。然而&#xff0c;传统人工检测端子焊点不仅效率低下&#xff0c;难以满足大规模生产需求&#xff0c;而且误判率高&#xff0c;无法精准把控产品质量&#xff0c;成为企业提质增效智…

电能质量在线监测分析装置支持实时监测、数据存储及远程传输,适用于电网、工业等场景

电能质量在线监测分析装置主要技术指标 2.1工作电源 交流&#xff1a;220V10% &#xff1b;50Hz0.5Hz&#xff1b;谐波畸变率不大于15&#xff05; 直流&#xff1a;220V10%&#xff0c;纹波系数不大于5% 2.2电流信号输入 输入方式&#xff1a;电流互感器输入&#xff1b; …

01分数规划

好久没发博客了……浅浅复活一下&#xff0c;讲个冷门些的算法。 算法目的&#xff1a;选出k组ai,bi使得 最大。 算法过程&#xff1a; 不妨考虑二分答案&#xff0c;那么答案的形式便是 的形式&#xff0c;则可通过移项转化为&#xff0c;进一步的&#xff0c;我们可以将…

网络安全防护技术

边界安全防护——防火墙 控制&#xff1a;在网络连接点上建立一个安全控制点&#xff0c;对进出数据进行限制隔离&#xff1a;将需要保护的网络与不可信任网络进行隔离&#xff0c;隐藏信息并进行安全防护记录&#xff1a;对进出数据进行检查&#xff0c;记录相关信息 防火墙…

课程分享 | 安全设计原则

讲师介绍 前言 在数字化时代&#xff0c;软件安全已从技术问题升级为关乎企业存亡的战略要务。从SolarWinds供应链攻击到Log4j漏洞风暴&#xff0c;一次次安全事件不断警示我们&#xff1a;传统的边界防护思维已无法应对日益复杂的威胁环境。面对不断演进的攻击手段&#xff0…

【数据结构 · 初阶】- 单链表

目录 一.相关指针知识点 二.链表 1.为什么学了顺序表还要学链表 2.优点 三.实现 1.链表的打印 —— 理解链表结构 (2) 物理结构图 2.链表的尾插 —— 入门 错误写法&#xff1a;tail ! NULL 总结&#xff1a; 正确代码物理图解&#xff1a; (2) 尾插整体代码 (思考…

在Linux系统命令行如何使用deepseek官方API调用AI大模型?

在Linux系统命令行如何调用deepseek官方API调用AI大模型&#xff1f; 书接上文&#xff1a; 同样的开头哈哈哈哈&#xff1a; ”在这个AI技术飞速发展的时代&#xff0c;每一个程序员都应该问问自己&#xff1a;如何将人工智能的强大能力融入到我们熟悉的操作系统中&#xff…

我开源了一个“宝藏”开源项目

我开源了一个“宝藏”开源项目 - AI需求分析项目 | 适合交作业和学习 &#x1f680; 前言 大家好&#xff01;最近在学习软件工程和大模型应用开发的过程中&#xff0c;我发现许多学生都遇到了需求分析AI的题目。把一份需求文档转化为用户故事、实体关系或数据库设计&#xff…

SmolDocling:一种超紧凑的视觉语言模型,用于端到端多模态文档转换

paper地址:SmolDocling: An ultra-compact vision-language model for end-to-end multi-modal document conversion Huggingface地址:SmolDocling-256M-preview 代码对应的权重文件:SmolDocling-256M-preview权重文件 一、摘要 以下是文章摘要的总结: SmolDocling 是一…

理解CSS3 的 max/min-content及fit-content等width值

本文首发在我的个人博客&#xff1a; 理解CSS3 的 max/min-content及fit-content等width值https://www.brandhuang.com/article/1744253362074 width/height 的属性值 fit-content 这是一个 CSS3 属性&#xff0c;用来设置元素的宽度和高度&#xff0c;值为 fit-content&#…

关键路径任务延误,如何快速调整

快速识别延误原因、优化资源配置、实施任务并行、调整任务优先级是关键路径任务延误后快速调整的有效方式。其中&#xff0c;快速识别延误原因尤为重要&#xff0c;需要项目管理者及时发现影响关键路径任务延误的核心问题&#xff0c;通过系统性的分析&#xff0c;确保延误的具…

Elasticsearch 全面解析

Elasticsearch 全面解析 前言一、简介核心特性应用场景 二、核心原理与架构设计1. 倒排索引&#xff08;Inverted Index&#xff09;2. 分片与副本机制&#xff08;Sharding & Replication&#xff09;3. 节点角色与集群管理 三、核心特点1. 灵活的查询语言&#xff08;Que…

linux入门四:Linux 编译器

一、C 语言编译器 GCC&#xff1a;开启编程之旅 1.1 GCC 安装&#xff1a;一站式工具链 GCC&#xff08;GNU Compiler Collection&#xff09;是 Linux 下最常用的 C/C 编译器&#xff0c;支持多种编程语言。安装命令&#xff08;适用于 Debian/Ubuntu 系统&#xff09;&…

springboot集成springcloud vault读值示例

接上三篇 Vault---机密信息管理工具安装及常用示例 Vault机密管理工具集群配置示例 vault签发根证书、中间证书、ca证书流程记录 项目里打算把所有密码都放到vault里管理&#xff0c;vault提供了springcloud vault用来在springboot里连接vault&#xff0c;启动加载vault里的值放…

edis 主从复制

Redis 主从复制是一种数据同步机制&#xff0c;主节点&#xff08;Master&#xff09;将数据复制到一个或多个从节点&#xff08;Slave&#xff09;&#xff0c;从 而实现数据备份、读写分离和高可用性。 1、解决我们的日常一个单机故障&#xff0c;而衍生出来 主从架构 2、…

机器视觉+深度学习,让电子零部件表面缺陷检测效率大幅提升

在精密加工的3C电子行业中&#xff0c;一抹0.1毫米的油渍&#xff0c;一粒肉眼难辨的灰尘或将引发整机性能隐患。当制造业迈入微米级品质竞争时代&#xff0c;产品表面看似微不足道的脏污缺陷&#xff0c;正成为制约企业高质量发展的隐形枷锁。分布无规律的污渍斑点、形态各异的…

Java基础关键_035_Lambda 表达式

目 录 一、引例&#xff1a;TreeSet 排序 1.实现 Comparable 接口 2.比较器 3.匿名内部类 4.Lambda 表达式 5.Lambda 表达式和匿名内部类的区别 二、函数式编程 三、Lambda 表达式的使用 1.无返回值函数式接口 &#xff08;1&#xff09;无返回值无参数 &#xff08;…

OPEX baota 2024.02.26

OPEX baota 2024.02.26 运维集成软件宝塔2024.02.26作废例子&#xff1a; 最重要的两个地方&#xff1a;上传文件 网站&#xff0c;重启应用服务器&#xff08;tomcat&#xff09; 其他很少用的

若依 前后端部署

后端&#xff1a;直接把代码从gitee上拉去到本地目录 (https://gitee.com/y_project/RuoYi-Vue ) 注意下redis连接时password改auth 后端启动成功 前端&#xff1a;运行前首先确保安装了node环境&#xff0c;随后执行&#xff1a; &#xff01;&#xff01;一定要用管理员权限…

LeetCode算法题(Go语言实现)_37

题目 给你一棵以 root 为根的二叉树&#xff0c;二叉树中的交错路径定义如下&#xff1a; 选择二叉树中 任意 节点和一个方向&#xff08;左或者右&#xff09;。 如果前进方向为右&#xff0c;那么移动到当前节点的的右子节点&#xff0c;否则移动到它的左子节点。 改变前进方…