当前位置: 首页 > news >正文

Linux多进程通信(4)——消息队列从入门到实战!

Linux多进程通信总结——进程间通信看这一篇足够啦!

1.基本介绍

1)消息队列的本质其实是一个内核提供的链表,内核基于这个链表,实现了一个数据结构,向消息队列中写数据,实际上是向这个数据结构中插入一个新结点;从消息队列汇总读数据,实际上是从这个数据结构中删除一个结点
2)消息队列独立于发送与接收进程,进程终止时,消息队列中的内容不会被删除,所以要记得删除消息队列
3)消息队列可以实现消息的
随机查询
消息不一定要以先进先出的次序读取,也可以按照消息的类型读取
4)Linux环境中,最多有256个消息队列,每个消息最大为8K字节,总大小不能超过16K,否则在send时会阻塞,可以通过更改内核设置的方式更改大小。
image.png

2.API介绍

1)获取消息队列键值

#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(char *pathname, char proj);

pathname:路径名,是必须存在的,ftok只是根据文件inode在系统内的唯一性来取一个数值,和文件的权限无关。
proj:1-255之间的数字
返回值: 生成一个独有的数,失败则返回-1
key 31-24 proj_id 低8位
key 23-16 pathname的st_dev属性的低8位
key 15-0 pathname的st_ino属性的低16位32位组合而成一个int值,就是我们的ftok的返回值了
根据路径名以及数字,合成系统中唯一的Key值

2)创建/获取消息队列

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg);

key:使用ftok获取到的唯一Key值
msgflag: 和其他的IPC通信一样,IPC_CREAT,如果消息队列对象不存在,则创建之,否则则进行打开操作。IPC_EXCL,如果消息对象不存在则创建之,否则产生一个错误并返回,可同时用IPC_CREATE | 0666
返回值:成功返回消息队列ID,失败则返回-1

3)msgsend发送消息

int msgsnd(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);

msgid :消息队列ID
msgptr:消息体,消息体的类型是一个结构体

msg_sz: 消息长度 消息体中的消息长度(不是一整个结构体的长度,只是mtext消息数据的长度
msgflag :发送flag 一般设置为0,阻塞式等待(消息队列满),也可以设置为 IPC_NOWAIT,则立刻返回
返回值:成功返回0,失败返回-1
调用成功后,发送内容的一个备份,会被放到消息队列中(这里会有个硬拷贝的过程)

4)msgrecv接收消息

ssize_t msgrcv(int msgid, const void *msgp, size_t msgsz, int msgtype, int msgflag)

msgid:消息队列ID
msgp: 接收到的消息体
msgsz: 接收消息的长度
msgtype :消息类型 ,对应发送时的m_type。
值为0:代表接收一个任意类型的消息
值大于0:获取消息类型为msgtype的第一个消息
值小于0:获取消息类型小于等于msgtype的第一个消息
msgflag :接收的flag一般设置为0,阻塞式等待
msgflg=IPC_NOWAIT,队列没有可读消息不等待,返回ENOMSG错误。
msgflg=MSG_NOERROR,消息大小超过msgsz时被截断
msgtype>0且msgflg=MSC_EXCEPT,接收类型不等于msgtype的第一条消息。
返回值:调用成功时,返回接收到消息的字节数,失败返回-1

调用成功时消息被复制到由msg_ptr指向的用户分配的缓存区中,然后删除消息队列中的对应消息(这里会有个硬拷贝的过程)

5)控制消息队列

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

msgid:消息队列id
cmd:控制消息队列的命令选项
IPC_STAT:把msgid_ds结构中的数据设置为消息队列的当前关联值,即用消息队列的当前关联值覆盖msgid_ds的值。
IPC_SET:如果进程有足够的权限,就把消息列队的当前关联值设置为msgid_ds结构中给出的值
IPC_RMID:删除消息队列

其实对于IPC通信来说,这些基本都是通用的~

3.例程

1)服务端

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <pthread.h>#define MSGQ_PATH "./"
#define MSGQ_PRI 100typedef struct {long mtype;char mtext[256];
} MSGQ_T;int iMsgId = 0;int main(int argc, char **argv)
{key_t msgkey = 0;msgkey = ftok(MSGQ_PATH, MSGQ_PRI);if (msgkey == -1){printf("ftok error, pid:%d\n", getpid());return -1;}iMsgId = msgget(msgkey, IPC_CREAT | 0644);if (iMsgId == -1){printf("msgget error, pid:%d\n", getpid());return -1;}printf("msgget success, pid:%d, key:%d, msgid:%d\n", getpid(), msgkey, iMsgId);while (1){MSGQ_T msgBuf = {0};int iMsgType = 0;printf("input message type:\n");//输入消息类型scanf("%d", &iMsgType);if (iMsgType == 0){printf("message type 0, break\n");break;}char acBuf[256] = {0};printf("input message to be send:\n");//输入消息信息scanf("%s", acBuf);msgBuf.mtype = iMsgType;strncpy(msgBuf.mtext, acBuf, sizeof(msgBuf.mtext) - 1);msgsnd(iMsgId, &msgBuf, sizeof(msgBuf), IPC_NOWAIT);printf("msgq:%d, send msgtype:%d, msgtext:%s \n", iMsgId, msgBuf.mtype, msgBuf.mtext);}msgctl(iMsgId, IPC_RMID, NULL);return 0;
}

2)客户端

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <pthread.h>#define MSGQ_PATH "./"
#define MSGQ_PRI 100typedef struct {long mtype;char mtext[256];
} MSGQ_T;int iMsgId = 0;
pthread_t msgqRecvThread = 0; void *msgqRecvThreadTask(void *arg)
{while (1){MSGQ_T msgBuf = {0};int ret = msgrcv(iMsgId, &msgBuf, sizeof(msgBuf), 0, 0);if (ret < 0){return NULL;}printf("msgq:%d, recv msgtype:%d, msgtext:%s, ret:%d \n", iMsgId, msgBuf.mtype, msgBuf.mtext, ret);}return NULL;
}int main(int argc, char **argv)
{key_t msgkey = 0;msgkey = ftok(MSGQ_PATH, MSGQ_PRI);if (msgkey == -1){printf("ftok error, pid:%d\n", getpid());perror("....");return -1;}iMsgId = msgget(msgkey, IPC_CREAT | 0644);if (iMsgId == -1){printf("msgget error, pid:%d\n", getpid());perror("....");return -1;}printf("msgget success, pid:%d, key:%d, msgid:%d\n", getpid(), msgkey, iMsgId);pthread_create(&msgqRecvThread, NULL, msgqRecvThreadTask, NULL);pthread_join(msgqRecvThread, NULL);return 0;
}

可以通过指令分别编译客户端和服务端并执行

gcc server.c -o server -lpthread
gcc client.c -o client -lpthread
./server
./client

在输入框输入消息后,便可以在client观察到消息接收啦
image.png
此时输入ipcs -q后能看到创建的消息队列
image.png
这里我显示有两个消息队列,因为上一个没有用msgctl删除。

当服务端和客户端程序都正常退出时,调用msgctl则会正常删除消息队列,在例程中的server端输入0即可!

相关文章:

Linux多进程通信(4)——消息队列从入门到实战!

Linux多进程通信总结——进程间通信看这一篇足够啦&#xff01; 1.基本介绍 1&#xff09;消息队列的本质其实是一个内核提供的链表&#xff0c;内核基于这个链表&#xff0c;实现了一个数据结构&#xff0c;向消息队列中写数据&#xff0c;实际上是向这个数据结构中插入一个…...

[Flutter]导入singular_flutter_sdk后运行到Android报错

问题&#xff1a; 接入归因之前&#xff0c;flutter项目一起正常。接入归因之后&#xff0c;iOS正常Android有问题。 dependencies: # Singular归因singular_flutter_sdk: ^1.3.3 针对 Flutter 的 Singular SDK 集成指南 https://support.singular.net/hc/zh-cn/articles/…...

ChatGPT新手指南:如何用AI写出专业学术论文

ChatGPT无限次数:点击直达 ChatGPT新手指南&#xff1a;如何用AI写出专业学术论文 在当今信息爆炸的时代&#xff0c;人工智能技术的快速发展为我们提供了许多新的可能性。ChatGPT作为一种先进的自然语言处理技术&#xff0c;不仅能够进行对话和文本生成&#xff0c;还可以辅助…...

【ZZULIOJ】1047: 对数表(Java)

目录 题目描述 输入 输出 样例输入 Copy 样例输出 Copy code 题目描述 输入两个正整数m和n&#xff0c;输出m到n之间每个整数的自然对数。 输入 输入包括两个整数m和n(m<n)&#xff0c;之间用一个空格隔开。 输出 每行输出一个整数及其对数&#xff0c;整数占4…...

thinkphp6使用阿里云SDK发送短信

使用composer安装sdk "alibabacloud/dysmsapi-20170525": "2.0.24"封装发送短信类 发送到的短信参数写在env文件里面的 #发送短信配置 [AliyunSms] AccessKeyId "" AccessKeySecret "" signName"" templateCode"&…...

file_get_contents(‘php://input‘); 这个postman要如何传参

在 Postman 中传递参数给 file_get_contents(php://input); 是通过请求的 Body 部分来实现的。使用 Postman 进行 API 接口测试时&#xff0c;可以按照以下步骤来传递参数&#xff1a; 打开 Postman 并创建一个新的请求。在请求的 URL 地址栏输入你的 API 地址。选择请求方法为…...

HDFS [MSST‘10] 论文阅读笔记

原论文:The Hadoop Distributed File System (MSST’10) HDFS关键技术要点概览 设计目标:HDFS旨在可靠地存储大型数据集,并以高带宽流式传输这些数据集到用户应用程序。它通过在大量服务器上分布存储和计算资源,使得资源可以随着需求的增长而扩展,同时保持经济高效。架构组…...

Feature Pyramid Networks for object detection

FPN 总述1.引言2.相关工作3. Feature Pyramid NetworksBottom-up pathwayTop-down pathway and lateral connections 4. 应用用于 RPN用于 Fast R-CNN 核心代码复现FPN网络结构ResNet Bottleneck完整代码 总述 下图中&#xff0c;蓝色边框表示的是特征图&#xff0c;边框越粗表…...

Linux下docker运行python

前言 本机开发环境众多&#xff0c;python版本都好多个&#xff0c;虽然可以通过conda管理多个虚拟环境&#xff0c;但还是不能像容器那样进行进程间的隔离。于是打算试下docker下运行python&#xff0c;而且生产环境很多时候也是用容器来跑应用&#xff0c;环境统一、方便扩容…...

MacOS下载和安装HomeBrew的详细教程

在MacOS上安装Homebrew的详细教程如下&#xff1a;&#xff08;参考官网&#xff1a;macOS&#xff08;或 Linux&#xff09;缺失的软件包的管理器 — Homebrew&#xff09; 步骤1&#xff1a;检查系统要求 确保你的MacOS版本至少为macOS Monterey (12) (or higher) 或更高版本…...

AI技术在金融领域/银行业的应用和风险

前言 随着科技的不断发展&#xff0c;人工智能&#xff08;AI&#xff09;技术已经在各行各业得到了广泛的应用&#xff0c;其中包括银行业。银行业作为经济的重要组成部分&#xff0c;一直在不断地探索和应用新技术&#xff0c;以提升服务效率、风险管理和客户体验。然而&…...

每日OJ题_两个数组dp⑤_力扣10. 正则表达式匹配

目录 力扣10. 正则表达式匹配 解析代码 力扣10. 正则表达式匹配 10. 正则表达式匹配 难度 困难 给你一个字符串 s 和一个字符规律 p&#xff0c;请你来实现一个支持 . 和 * 的正则表达式匹配。 . 匹配任意单个字符* 匹配零个或多个前面的那一个元素 所谓匹配&#xff0c…...

开源区块链系统/技术 总结(欢迎补充,最新)

一、联盟链 1. FISCO BCOS FISCO BCOS 2.0 技术文档 — FISCO BCOS 2.0 v2.9.0 文档https://fisco-bcos-documentation.readthedocs.io/ 2. ChainMaker&#xff08;长安链&#xff09; 文档导航 — chainmaker-docs v2.3.2 documentationhttps://docs.chainmaker.org.cn/v2…...

LeetCode 994—— 腐烂的橘子

阅读目录 1. 题目2. 解题思路3. 代码实现 1. 题目 2. 解题思路 1.记录下初始新鲜橘子的位置到 notRotting&#xff0c;我们按照行把二维数组拉成一维&#xff0c;所以&#xff0c;一个vector 就可以实现了&#xff1b;2.如果没有新鲜橘子&#xff0c;那么第 0 分钟所有橘子已经…...

向上向下采样

在数字图像处理中&#xff0c;向上采样&#xff08;upsampling&#xff09;和向下采样&#xff08;downsampling&#xff09;是两种常见的操作&#xff0c;用于改变图像的分辨率。 向上采样&#xff08;Upsampling&#xff09;&#xff1a; 向上采样是指增加图像的分辨率&…...

Leetcode面试经典150_Q169多数元素

题目&#xff1a; 给定一个大小为 n 的数组 nums &#xff0c;返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊n/2⌋ 的元素。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 解题思路&#xff1a; 1. 注意“大于 ⌊n/2⌋”&#xff0c;…...

Spring Cloud微服务入门(五)

Sentinel的安装与使用 安装部署Sentinel 下载Sentinel&#xff1a; https://github.com/alibaba/Sentinel/releases Sentinel控制台 https://localhost:8080 用户和密码为sentinel 使用Sentinel 加依赖&#xff1a; 写配置&#xff1a; 输入&#xff1a; java -Dserver.po…...

负荷预测 | Matlab基于TCN-GRU-Attention单输入单输出时间序列多步预测

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab基于TCN-GRU-Attention单输入单输出时间序列多步预测&#xff1b; 2.单变量时间序列数据集&#xff0c;采用前12个时刻预测未来96个时刻的数据&#xff1b; 3.excel数据方便替换&#xff0c;运行环境matlab20…...

SpringBoot整合Spring Data JPA

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉🍎个人主页:Leo的博客💞当前专栏: 循序渐进学SpringBoot ✨特色专栏: MySQL学习 🥭本文内容: SpringBoot整合Spring Data JPA 📚个人知识库: Leo知识库,欢迎大家访问 1.…...

机器学习(五) -- 监督学习(2) -- k近邻

系列文章目录及链接 目录 前言 一、K近邻通俗理解及定义 二、原理理解及公式 1、距离度量 四、接口实现 1、鸢尾花数据集介绍 2、API 3、流程 3.1、获取数据 3.2、数据预处理 3.3、特征工程 3.4、knn模型训练 3.5、模型评估 3.6、结果预测 4、超参数搜索-网格搜…...

【.NET全栈】ZedGraph图表库的介绍和应用

文章目录 一、ZedGraph介绍ZedGraph的特点ZedGraph的缺点使用注意事项 二、ZedGraph官网三、ZedGraph的应用四、ZedGraph的高端应用五、、总结 一、ZedGraph介绍 ZedGraph 是一个用于绘制图表和图形的开源.NET图表库。它提供了丰富的功能和灵活性&#xff0c;可以用于创建各种…...

vivado 设计调试

设计调试 对 FPGA 或 ACAP 设计进行调试是一个多步骤迭代式流程。与大多数复杂问题的处理方式一样 &#xff0c; 最好先将 FPGA 或 ACAP 设计调试流程细分为多个小部分 &#xff0c; 以便集中精力使设计中的每一小部分能逐一正常运行 &#xff0c; 而不是尝试一次性让整 个…...

Python3 replace()函数使用详解:字符串的艺术转换

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …...

【C++】用红黑树封装map和set

我们之前学的map和set在stl源码中都是用红黑树封装实现的&#xff0c;当然&#xff0c;我们也可以模拟来实现一下。在实现之前&#xff0c;我们也可以看一下stl源码是如何实现的。我们上篇博客写的红黑树里面只是一个pair对象&#xff0c;这对于set来说显然是不合适的&#xff…...

一些好玩的东西

这里写目录标题 递归1.递归打印数组和链表?代码实现原理讲解二叉树的 前 中 后 序位置 参考文章 递归 1.递归打印数组和链表? 平常我们打印数组和链表都是 迭代 就好了今天学到一个新思路–>不仅可以轻松正着打印数组和链表 , 还能轻松倒着打印(用的是二叉树的前中后序遍…...

微电网优化:基于巨型犰狳优化算法(Giant Armadillo Optimization,GAO)的微电网优化(提供MATLAB代码)

一、微电网优化模型 微电网是一个相对独立的本地化电力单元&#xff0c;用户现场的分布式发电可以支持用电需求。为此&#xff0c;您的微电网将接入、监控、预测和控制您本地的分布式能源系统&#xff0c;同时强化供电系统的弹性&#xff0c;保障您的用电更经济。您可以在连接…...

java锁

乐观锁 乐观锁是一种乐观思想&#xff0c;即认为读多写少&#xff0c;遇到并发写的可能性低&#xff0c;每次去拿数据的时候都认为别人不会修改&#xff0c;所以不会上锁&#xff0c;但是在更新的时候会判断一下在此期间别人有没有去更新这个数据&#xff0c;采取在写时先读出…...

QA测试开发工程师面试题满分问答6: 如何判断接口功能正常?从QA的角度设计测试用例

判断接口功能是否正常的方法之一是设计并执行相关的测试用例。下面是从测试QA的角度设计接口测试用例的一些建议,包括功能、边界、异常、链路、上下游和并发等方面: 通过综合考虑这些测试维度,并设计相应的测试用例,可以更全面地评估接口的功能、性能、安全性、数据一致…...

vue 双向绑定

双向绑定&#xff1a;双方其中一方改变&#xff0c;另外一方也会跟着改变。 data() { return {inputValue: ,list: [],message: hello,checked: true,radio: ,select: [],options: [{text: A, value:{value: A}},{text: B, value:{value: B}},{text: C, value:{value: C}}], }…...

python--异常处理

异常处理 例一&#xff1a; try: #可能出现异常代码 except&#xff1a; #如果程序异常&#xff0c;则立刻进入这儿 [finally: #不管是否捕获异常&#xff0c;finally语法快必须要执行&#xff01;&#xff01;&#xff01; #资源关闭&#xff0c;等各种非常重要的操作&…...