Linux进程通信——消息队列

2023-11-02

消息队列概述

消息队列是存在Linux内核中,以链表形式来存消息
一个消息队列由一个标识符(即队列ID)来标识。
用户进程可以向消息队列添加消息,也可以向消息队列读取消息。

特点
消息队列是面向记录的,其中的消息具有特定的格式(结构体保存)
消息队列独立于发送与接收进程,哪怕进程退出后消息还会保存
消息队列中的消息是可以任意读取的,可以按照类型来读取

一般形式如下:

// 创建或打开消息队列:成功返回队列ID,失败返回-1
int msgget(key_t key, int flag);
// 添加消息:成功返回0,失败返回-1
int msgsnd(int msqid, const void *ptr, size_t size, int flag);
// 读取消息:成功返回消息数据的长度,失败返回-1
int msgrcv(int msqid, void *ptr, size_t size, long type,int flag);
// 控制消息队列:成功返回0,失败返回-1
int msgctl(int msqid, int cmd, struct msqid_ds *buf);

消息队列发送端

#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <string.h>
//int msgget(key_t key, int msgflg);
//key_t ftok(const char *pathname, int proj_id);
 struct msgbuf {
               long mtype;       /* message type, must be > 0 */
               char mtext[128];    /* message data */
           };//消息队列所用结构体

int main()
{
   struct msgbuf sendbuf = {111,"this is send program!!!"};//消息类型与发送内容
   key_t key;
   key = ftok(".",'30');//获取IPC键值
   if(key<0){
     printf("creat key number fail!\n");
   }//
     printf("%x\n",key);
   int msgid = msgget(key, IPC_CREAT|0777);//创建消息队列
   if(msgid==-1){
      printf("creat que error!\n");
      perror("why");
   }
   printf("%d\n",msgid);
   // int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
   msgsnd(msgid,&sendbuf,strlen(sendbuf.mtext),0);//发送消息
   msgctl(msgid, IPC_RMID,NULL);//删除队列
   return 0;
}

我们将“this is send programm!!!”发送到消息队列中

消息队列接收端

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
//int msgget(key_t key, int msgflg);
//key_t ftok(const char *pathname, int proj_id);
 struct msgbuf {
               long mtype;       /* message type, must be > 0 */
               char mtext[128];    /* message data */
           };

int main()
{
   struct msgbuf readbuf;
   key_t key;
   key = ftok(".",'1');
   int msgid = msgget(key, IPC_CREAT|0777);
   if(msgid==-1){
      printf("creat que error!\n");
      perror("why");
   }
   msgrcv(msgid,&readbuf,sizeof(readbuf.mtext),111,0);//一样的键值和类型
   printf("%s\n",readbuf.mtext);
   printf("get success\n");


}

效果如下:
在这里插入图片描述
当同时运行两个程序时,消息就能接收

补充key值作用

进程间通信(IPC)
有两个东西可以标识一个IPC结构:标识符(ID)和键(key)。

键值(ID)
ID是IPC结构的内部名,用来确保使用同一个通讯通道(比如说这个通讯通道就是消息队列)。内部即在进程内部使用,这样的标识方法是不能支持进程间通信的。

标识符(key)
key就是IPC结构的外部名。当多个进程,针对同一个key调用get函数(msgget等),这些进程得到的ID其实是标识了同一个IPC结构。多个进程间就可以通过这个IPC结构通信。

消息队列互相发送接收

我们分为夫妻两个进程
互相发送消息
夫进程如下:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <string.h>
//int msgget(key_t key, int msgflg);
//key_t ftok(const char *pathname, int proj_id);
 struct msgbuf {
               long mtype;       /* message type, must be > 0 */
               char mtext[128];    /* message data */
           };

int main()
{
   struct msgbuf readbuf;
   struct msgbuf sendbuf = {520,"form husband:you are my wife!love you so much"};
   key_t key;
   key = ftok(".",30);
   if(key<0){
     printf("creat key number fail!\n");
   }
     printf("%x\n",key);
   int msgid = msgget(key, IPC_CREAT|0777);
   if(msgid==-1){
      printf("creat que error!\n");
      perror("why");
   }
   printf("%d\n",msgid);
   // int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
   msgsnd(msgid,&sendbuf,strlen(sendbuf.mtext),0);
   msgrcv(msgid,&readbuf,sizeof(readbuf.mtext),1314,0);
   printf("%s\n",readbuf.mtext);
   msgctl(msgid,IPC_RMID,NULL);
   return 0;
}

妻进程

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <string.h>
//int msgget(key_t key, int msgflg);
//key_t ftok(const char *pathname, int proj_id);
 struct msgbuf {
               long mtype;       /* message type, must be > 0 */
               char mtext[128];    /* message data */
           };

int main()
{
   struct msgbuf readbuf;
   struct msgbuf sendbuf = {1314,"form wife:you are my husband!love you so much"};
   key_t key;
   key = ftok(".",30);
   if(key<0){
     printf("creat key number fail!\n");
   }
     printf("%x\n",key);
   int msgid = msgget(key, IPC_CREAT|0777);
   if(msgid==-1){
      printf("creat que error!\n");
      perror("why");
   }
   printf("%d\n",msgid);
   // int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
   msgsnd(msgid,&sendbuf,strlen(sendbuf.mtext),0);
   msgrcv(msgid,&readbuf,sizeof(readbuf.mtext),520,0);
   printf("%s\n",readbuf.mtext);
   msgctl(msgid,IPC_RMID,NULL);
   return 0;
}

在这里插入图片描述
两个进程通信可以使用相同的key值但接收和发送通道的类型要不同!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux进程通信——消息队列 的相关文章

  • 多处理:仅使用物理核心?

    我有一个函数foo它消耗大量内存 我想并行运行多个实例 假设我有一个有 4 个物理核心的 CPU 每个核心有两个逻辑核心 我的系统有足够的内存来容纳 4 个实例foo并行但不是 8 个 此外 由于这 8 个核心中的 4 个是逻辑核心 我也不
  • 无法使用maven编译java项目

    我正在尝试在 java 16 0 1 上使用 maven 构建 IntelliJ 项目 但它无法编译我的项目 尽管 IntelliJ 能够成功完成 在此之前 我使用maven编译了一个java 15项目 但我决定将所有内容更新到16 0 1
  • CoAP数据包的大小是多少?

    我是这项技术的新手 有人可以帮助我了解一些疑问吗 Q 1 CoAP数据包的大小是多少 我知道有 4 字节固定标头 但是包括标头 选项和负载在内的最大大小限制是多少 Q 2 有像MQTT那样的Keep Alive的概念吗 它在UDP上工作 它
  • 我不明白 execlp() 在 Linux 中如何工作

    过去两天我一直在试图理解execlp 系统调用 但我还在这里 让我直奔主题 The man pageexeclp 将系统调用声明为int execlp const char file const char arg 与描述 execl exe
  • MySQL 中的创建/写入权限

    我的设备遇到一些权限问题SELECT INTO OUTFILE陈述 当我登录数据库并执行简单的导出命令时 例如 mysql gt select from XYZ into outfile home mropa Photos Desktop
  • 如何在基于 Linux 的系统上的 C 程序中使用 mqueue?

    如何在基于 Linux 的系统上的 C 程序中使用 mqueue 消息队列 我正在寻找一些好的代码示例 可以展示如何以正确且正确的方式完成此操作 也许是一个操作指南 下面是一个服务器的简单示例 该服务器接收来自客户端的消息 直到收到告诉其停
  • Linux - 从第二个选项卡获取文本

    假设我们有这样的文件 一些文本11 一些文本12 一些文本13 一些文本21 一些文本22 一些文本23 文本由制表符分隔 我们知道第 1 列中的一些文本 但希望从第 2 列中获取文本 我知道我可以通过以下方式获取线路 grep somet
  • 子目录中的头文件(例如 gtk/gtk.h 与 gtk-2.0/gtk/gtk.h)

    我正在尝试使用 GTK 构建一个 hello world 其中包括以下行 include
  • 确定我可以向文件句柄写入多少内容;将数据从一个 FH 复制到另一个 FH

    如何确定是否可以将给定数量的字节写入文件句柄 实际上是套接字 或者 如何 取消读取 我从其他文件句柄读取的数据 我想要类似的东西 n how much can I write w handle n read r handle buf n a
  • Urwid:使光标不可见

    我正在使用 urwid 它是一个用于在 ncurses 中设计终端用户界面的 Python 框架 但有一件事我在 urwid 中无法做到 而这在 Curses 中很容易做到 使光标不可见 现在 选择按钮时光标是可见的 而且看起来很丑 有办法
  • Fortran gfortran linux 中的“分段错误(核心转储)”错误

    我正在创建一个程序 该程序将分析目录中的文件 fits 然后它将在另一个目录中创建另一个文件 txt 它只是一个转换器 当我尝试执行该程序 编译正常 时 它给了我一条错误消息 程序收到信号 SIGSEGV 分段错误 无效的内存引用 此错误的
  • 如何查看 Ubuntu 上的 Binutils 版本?

    我已经搜索过 但没有找到一个选项来告诉我我的 Ubuntu 上有哪个版本的 binutils 或者至少我不知道如何解释它 gcc v 没有透露任何有关 binutils 的信息 ld v 告诉我GNU ld GNU Binutils for
  • 高效的内存屏障

    我有一个多线程应用程序 其中每个线程都有一个整数类型的变量 这些变量在程序执行期间递增 在代码中的某些点 线程将其计数变量与其他线程的计数变量进行比较 现在 我们知道在多核上运行的线程可能会无序执行 一个线程可能无法读取其他线程的预期计数器
  • 如何查询X11显示分辨率?

    这似乎是一个简单的问题 但我找不到答案 如何查询 通过 X11 存在哪些监视器及其分辨率 查看显示宏 http tronche com gui x xlib display display macros html and 屏幕宏 http
  • 如何允许应用程序声明“https”方案 URI? (即如何从 https URL 打开桌面应用程序?)

    目前我正在尝试为 OAuth 2 0 授权流程创建一个客户端 实际上是一个本机应用程序 并且在规范中就在这儿 https www rfc editor org rfc rfc8252 section 7 2据说有 3 种方法来处理重定向 U
  • Python 脚本作为 Linux 服务/守护进程

    Hallo 我试图让 python 脚本作为服务 守护进程 在 ubuntu linux 上运行 网络上存在多种解决方案 例如 http pypi python org pypi python daemon http pypi python
  • Gearman,php 扩展问题:使用终端在 .. 中找不到类“GearmanWorker”,但可以在浏览器上使用

    我最近在 ubuntu 10 04 上安装了 gearman 并安装了它的 pecl 扩展 现在 当我在浏览器中运行一个 php 文件时 其中包含 client new GearmanWorker die var Dump client I
  • vagrant ssh -c 并在连接关闭后保持后台进程运行

    我正在编写一个脚本来启动和后台流浪机器内的进程 似乎每次脚本结束和 ssh 会话结束时 后台进程也会结束 这是我正在运行的命令 vagrant ssh c cd vagrant src nohup python hello py gt he
  • 让 TeXstudio 在 linux mint 中工作:找不到文件“url.sty”。

    刚刚切换到 Linux Mint 以前的顽固 Windows 用户 我在尝试安装 TeXstudio 时遇到一些问题 Sudo apt get install texstudio 给了我一个正确的安装 至少 我是这么认为的 但是当我尝试构建
  • 嵌入式linux编写AT命令

    我在向 GSM 模块写入 AT 命令时遇到问题 当我使用 minicom b 115200 D dev ttySP0 term vt100 时它工作完美 但我不知道如何在 C 代码中做同样的事情 我没有收到任何错误 但模块对命令没有反应 有

随机推荐

  • Vue中组件和插件有什么区别?

    一 组件是什么 组件就是把图形 非图形的各种逻辑均抽象为一个统一的概念 组件 来实现开发的模式 在Vue中每一个 vue文件都可以视为一个组件 组件的优势 降低整个系统的耦合度 在保持接口不变的情况下 我们可以替换不同的组件快速完成需求 例
  • 大数据学习——Zookeeper集群搭建

    一 Zookeeper入门 1 概述 Zookeeper是一个开源的分布式的 为分布式框架提供协调服务的Apache项目 2 特点 1 Zookeeper 一个领导者 Leader 多个跟随者 Follower 组成的集群 2 集群中只要有
  • typescript开发electron程序的环境搭建过程

    1 安装nodejs 2 安装vs2013 或者vs2015 下载对应的typescript插件 3 创建项目 4 npm install g tsd 5 tsd install react global save tsd install
  • 模拟双色球系统-判断中奖情况

    package Java project 1 import java util Random import java util Scanner public class Java project 1 public static void m
  • argparser中的参数解释以及required参数在pycharm中的运行方式

    在argparser包时 其中add argumenet 函数有很多参数 name or flags 一个命名或者一个选项字符串的列表 例如 foo 或 f foo action 当参数在命令行中出现时使用的动作基本类型 nargs 命令行
  • Python 入门之控制结构 - 顺序与选择结构——第1关:顺序结构

    Python 入门之控制结构 顺序与选择结构 第1关 顺序结构 任务描述 程序最基本的结构就是顺序结构 顺序结构就是程序按照语句顺序 从上到下依次执行各条语句 本关要求学习者理解顺序结构 并对输入的三个数changeone changetw
  • 智能家居 (6) ——语音识别线程控制

    目录 语音识别线程控制代码 inputCommand h mainPro c voiceControl c 代码测试 往期文章 语音识别线程控制代码 inputCommand h include
  • fwrite函数的用法

    fwrite函数就是写文件的函数 它的函数原型如下 fwrite const void buffer size t size size t count FILE stream 可以看到这个函数的参数有四个 buffer 数据存储的地址 si
  • 点云高度归一化处理(附 python 代码)

    gt 由于不同地物之间存在着高程的差异 为了去除地形起伏对点云数据高程值的影响 所以需要根据提取出的地面点进行点云归一化处理 这一步是很多算法的基础 可以提高后续点云分类或分割的准确度等 如下图所示 gt 归一化的过程其实相对简单 遍历每一
  • 贪心算法力扣刷题练习(含思路与题解)

    贪心算法 保证每次操作都是局部最优 使得最终结果也是全局最优的 需要找到贪心的策略 使得每次的最优能保证全局最优 通常需要排序 根据排序需求 自定义比较函数 sort a begin a end vector
  • protobuf c++编程笔记

    文章目录 字段内容的定义 修饰符 字段类型 引用方式 不同字段的方法 1 optional修饰的基本类型 2 optional修饰的对象类型 3 repeated修饰的基本类型 4 repeated修饰的对象类型 序列化 反序列化 字段内容
  • Vue + 高德地图 + 三维模型

    一 创建高德的kek和密钥 根据需求选择服务平台 我选择的是web端 JS API 二 在vue中引入高德地图 在public文件下找到index html文件引入你的key值 参考 https lbs amap com demo jsap
  • Could not resolve com.android.tools.build:gradle:4.0.0.

    打开别人发过来的项目的时候gradle一直下载不下来 然后报错 尝试了很多办法 最后在用户变量种添加 Android SDK ROOT 自己的Android SDK路径 gradle 下载成功 可能遇到的具体错误问题不一样仅供参考
  • CentOS8基础篇15:防火墙命令配置

    一 防火墙服务 1 启动 关闭 重启防火墙服务 systemctl start firewalld service systemctl stop firewalld service systemctl restart firewalld s
  • ES 查询不稳定现象及解决方案

    问题描述 对于相同的查询语句 ES 查询返回不同的检索内容 示例 1 filter match content 宝骏510 order score size 10 在上面的示例中可以看到推荐句子的第二句和第三句的顺序发生了变化 产生原因 官
  • spring事务的隔离级别。如何避免脏读或者幻读

    事务隔离级别为四个等级 默认是数据库的隔离级别 需要去数据库查询一下隔离级别 1 查看当前会话隔离级别 select tx isolation 2 查看系统当前隔离级别 select global tx isolation 隔离级别 Iso
  • unity MeshCollider组件

    在应用MeshCollider组件中的一个属性 Convex 这个功能很好用 但是他也是有一个坑在里面 他的好处 当你点击之后他会自动根据模型自动生成一个碰撞器 这个是不规则的碰撞器 他的坏处 没有点击 Convex 时候 比如当你有一个物
  • Commond:命令模式

    命令模式即将请求封装为对象Commond 执行者可以执行多个操作 即执行者才是操作真正的实现者 设其为操作0 9 每个操作都封装了一个对应的Commond类 当该Commond被调用时 Commond会令执行者执行其对应的操作 用户需要执行
  • 文化:测试团队建设--读书会

    如何做管理 曾经很迷茫 一路跌跌撞撞 慢慢的发现了 想要做好管理 团队文化和团队建设也是管理的重要环节 其实在一个大的测试团队里 有很多测试同学相互之间是没有交集的 如何让大家熟悉团结起来 团队建设是其中一个方法 下面和大家分享 团队建设
  • Linux进程通信——消息队列

    Linux进程通信 消息队列 消息队列概述 消息队列发送端 消息队列接收端 补充key值作用 消息队列互相发送接收 消息队列概述 消息队列是存在Linux内核中 以链表形式来存消息 一个消息队列由一个标识符 即队列ID 来标识 用户进程可以