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

【IPC】消息队列

1、IPC对象

除了最原始的进程间通信方式信号、无名管道和有名管道外,还有三种进程间通信方式,这
三种方式称之为IPC对象
IPC对象分类:消息队列、共享内存、信号量(信号灯集)
IPC对象也是在内核空间开辟区域,每一种IPC对象创建好之后都会将其设置为全局,并且
会给其分配一个编号,只要找到唯一的这个编号就可以进行通信,所以不相关的进程可以通
过IPC对象通信。
IPC对象创建好之后,会在当前系统中可见,只要不删除或者不关闭系统,就会一直存在。
查看已经创建的IPC对象:
  ipcs 查看当前系统中所有创建的 IPC 对象
  ipcs ‐q 查看创建的消息队列
  ipcs ‐m 查看创建的共享内存
  ipcs ‐s 查看信号量
  ipcrm 删除 IPC 对象
  例如: ipcrm ‐q msqid 删除标号为 msqid 的消息队列

2、消息队列的概述

2.1 消息队列的概念

消息队列是消息的链表,存放在内存中,由内核维护
消息队列的特点
1、消息队列中的消息是有类型的。
2、消息队列中的消息是有格式的。
3、消息队列可以实现消息的随机查询。消息不一定要以先进先出的次序读取,编程时可以
按消息的类型读取
4、消息队列允许一个或多个进程向它写入或者读取消息。
5、与无名管道、命名管道一样,从消息队列中读出消息,消息队列中对应的数据都会被删
6、每个消息队列都有消息队列标识符,消息队列的标识符在整个系统中是唯一的。
7、只有内核重启或人工删除消息队列时,该消息队列才会被删除。若不人工删除消息队
列,消息队列会一直存在于系统中。
在ubuntu 12.04中消息队列限制值如下:
每个消息内容最多为8K字节
每个消息队列容量最多为16K字节
系统中消息队列个数最多为1609个
系统中消息个数最多为16384个
System V提供的IPC通信机制 需要一个key值通过key值就可在系统内获得一个唯一的消
息队列标识符
key值可以是人为指定的,也可以通过ftok函数获得
如果多个进程想通过IPC对象通信,则必须找到唯一的标识,而唯一的标识是由key决定
的,所以只要key知道,则就可以实现多个进程通信
(另外,Posix IPC的操作稍有不同,后面补充)

2.2 ftok函数

ftok - convert a pathname and a project identifier to a System V IPC key
 
  #include <sys/types.h>
  #include <sys/ipc.h>
  key_t ftok ( const char *pathname, int proj_id );
  功能:通过文件名和目标值共同创造一个键值并返回值
  参数:
           pathname :任意一个文件名(文件名或者目录名)
         proj_id:目标值,范围一般是 0~127
  返回值:
                  成功:键值
                  失败: ‐1
  如果使用 ftok 函数获取键值,得到的键值是由 ftok 的第一个   参数对应文件的信息和第二个参数一起决定的
#include <sys/types.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <stdlib.h>int main(int argc, char const *argv[])
{//使用ftok函数获取键值//只要保证ftok的第一个参数对应的文件和第二个参数值相同,则不管程序运行多少遍或者多少个进程或者键值//键值一定都是唯一的key_t mykey;mykey = ftok("test",666);if(mykey==-1){perror("fail to ftok");exit(1);}
printf("mykey = %#x\n", mykey);return 0;
}

3、消息队列操作

3.1创建消息队列 -- msgget()

  #include <sys/types.h>
  #include <sys/ipc.h>
  #include <sys/msg.h>
  int msgget ( key_t key, int msgflg );
          功能:创建一个消息队列,得到消息队列的 id
参数:
          key :键值,唯一的键值确定唯一的消息队列
                  方法 1 :任意指定一个数
                  方法 2 :使用 ftok 函数获取键值
          msgflg :消息队列的访问权限,
          一般设置为 IPC_CREAT | IPC_EXCL | 0777 或者 IPC_CREAT | 0777
  返回值:
          成功:消息队列的 id
        失败:‐1
查看消息队列
  ipcs ‐q
  删除消息队列
  ipcrm ‐q msqid
测试msgget
#include <sys/types.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/msg.h>int main(int argc, char const *argv[])
{key_t mykey;mykey = ftok("test", 666);if (mykey == -1){perror("fail to ftok");exit(1);}printf("mykey = %#x\n", mykey);// 通过msgget函数创建一个消息队列int msgid;msgid = msgget(mykey, IPC_CREAT | 0666);if (msgid == -1){perror("fail to msgget");exit(1);}printf("msgid = %d\n", msgid);system("ipcs -q");return 0;
}

3.2 发送消息-- msgsnd()

  # 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
        消息队列的id
msgp
        要写入的数据,需要自己定义结构体
struct struct_name {
          long mtype ; // 消息的编号,必须大于 0
          char mtext [ 128 ]; // 消息正文,可以定义多个成员
          ...
  }
  msgsz :消息正文的大小,不包括消息的编号长度
  msgflg :标志位
          0 阻塞
          IPC_NOWAIT 非阻塞
  返回值:
          成功: 0
          失败: 1
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>#define N 128typedef struct 
{long msg_type; //消息类型,必须在结构体的第一个位置并且类型必须是longchar msg_text[N]; //消息正文,也可以有多个成员并且类型也可以是任意
}MSG ;#define MSG_SIZE (sizeof(MSG)-sizeof(long))
int main(int argc, char const *argv[])
{key_t mykey;mykey = ftok("test", 666);if (mykey == -1){perror("fail to ftok");exit(1);}printf("mykey = %#x\n", mykey);// 通过msgget函数创建一个消息队列int msgid;msgid = msgget(mykey, IPC_CREAT | 0666);if (msgid == -1){perror("fail to msgget");exit(1);}//printf("msgid = %d\n", msgid);system("ipcs -q");MSG msg1 ={1,"hello world"};
MSG msg2 ={3,"UCC"};MSG msg3 ={2,"giant"};MSG msg4 ={4,"美利达"};if(msgsnd(msgid,&msg1,MSG_SIZE,0)==-1){perror("fail to send");exit(1);
}if(msgsnd(msgid,&msg2,MSG_SIZE,0)==-1){perror("fail to send");exit(1);
}
if(msgsnd(msgid,&msg3,MSG_SIZE,0)==-1){perror("fail to send");exit(1);
}
if(msgsnd(msgid,&msg4,MSG_SIZE,0)==-1){perror("fail to send");exit(1);
}system("ipcs -q");return 0;
}

3.3 消息接收--msgrcv()

# include <sys/ipc.h>
# include <sys/msg.h>
  ssize_t msgrcv ( int msqid , void * msgp , size_t msgsz ,
  long msgtyp , int msgflg );
  功能:从消息队列中接收数据(读操作),接收的数据会从消息队列中删除
  参数:
  msqid
        消息队列id
  msgp
        保存接收到的数据的结构体
        struct struct_name {
                long mtype ; // 消息的编号,必须大于 0
                char mtext [ 128 ]; // 消息正文,可以定义多个成员
        }
  msgsz
        消息正文的大小
  msgtyp :设置要接收哪个消息
          0 按照写入消息队列的顺序依次读取
          > 0 只读取消息队列中消息编号为当前参数的第一个消息
          < 0 只读取消息队列中小于等于当前参数的绝对中内最小的第一个消息
 
msgflg :标志位
        0 阻塞
          IPC_NOWAIT 非阻塞
  返回值:
          成功:接收到的消息正文的长度
          失败: 1
#include <sys/types.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/msg.h>#define N 128
typedef struct 
{long msg_type; //消息类型,必须在结构体的第一个位置并且类型必须是longchar msg_text[N]; //消息正文,也可以有多个成员并且类型也可以是任意
}MSG ;#define MSG_SIZE (sizeof(MSG)-sizeof(long))int main(int argc, char const *argv[])
{key_t mykey;mykey = ftok("test", 666);if (mykey == -1){perror("fail to ftok");exit(1);}printf("mykey = %#x\n", mykey);// 通过msgget函数创建一个消息队列int msgid;msgid = msgget(mykey, IPC_CREAT | 0666);if (msgid == -1){perror("fail to msgget");exit(1);}//printf("msgid = %d\n", msgid);system("ipcs -q");//通过msgrcv函数接收消息队列中的信息(读操作)
//注意:如果没有第四个参数指定的消息时,msgrcv函数会阻塞等待
MSG msg;
//如果第四个参数为0,则按照先进先出的方式读取数据//if(msgrcv(msgid,&msg,MSG_SIZE,0,0))//如果第四个参数为>0,则获取当前值得消息类型的数据
//if(msgrcv(msgid, &msg, MSGTEXT_SIZE, 2, 0) == ‐1)//如果第四个参数为<0,则获取当前值得绝对值内消息类型最小的数据if(msgrcv(msgid, &msg, MSG_SIZE, -3, 0) == -1){perror("fail to msgrcv");exit(1);}printf("recv_msg = %s\n", msg.msg_text);system("ipcs -q");return 0;
}

相关文章:

【IPC】消息队列

1、IPC对象 除了最原始的进程间通信方式信号、无名管道和有名管道外&#xff0c;还有三种进程间通信方式&#xff0c;这 三种方式称之为IPC对象 IPC对象分类&#xff1a;消息队列、共享内存、信号量(信号灯集) IPC对象也是在内核空间开辟区域&#xff0c;每一种IPC对象创建好…...

内网穿透工具NPS(保姆级教程)

前言&#xff1a; 有时候我们受限于硬件设备和网络的的问题&#xff0c;无法将内网的大容量、高性能存储设备或计算设备对外访问。这个时候就会变的特别苦恼&#xff0c;上云呢成本太大&#xff0c;不用云呢公网又无法直接访问&#xff0c;这个时候怎么办呢&#xff0c;NPS它来…...

最长公共子序列问题

构造最长公共子序列为什么要这样构造序列 for(int i1;i<n;i){int k;cin>>k;b[k]i;}for(int i1;i<n;i){int k;cin>>k;a[i]b[k];}并且为什么要求上升序列&#xff0c;是有什么数学知识包含在其中吗&#xff1f; 为什么在求最长公共子序列时&#xff0c;f[mid]大…...

服务器数据恢复—热备盘同步中断导致Raid5数据丢失的数据恢复案例

服务器数据恢复环境&#xff1a; 某单位一台服务器上有一组raid5阵列&#xff0c;该raid5阵列有15块成员盘。上层是一个xfs裸分区&#xff0c;起始位置是0扇区。 服务器故障&检测&#xff1a; 服务器raid5阵列中有硬盘性能表现不稳定&#xff0c;但是由于管理员长时间没有关…...

桥接模式-C++实现

桥接模式是一种结构型设计模式&#xff0c;它是将抽象部分和实现部分隔离&#xff0c;通过组合关系将抽象部分和实现部分解耦&#xff0c;使它们可以独立变化。 因此&#xff0c;桥接模式可以很好的处理两个或两个以上维度的变化。 举一个例子说明&#xff1a; 假设我们现在…...

PHP字符串函数的解析

在PHP中&#xff0c;字符串是一种常见的数据类型&#xff0c;用于存储和操作文本数据。PHP提供了丰富的字符串函数&#xff0c;用于执行各种字符串操作&#xff0c;包括截取、连接、替换、搜索等。在这篇文章中&#xff0c;我们将深入解析一些常用的PHP字符串函数&#xff0c;以…...

科研学习|研究方法——使用python强大的Statsmodel 执行假设检验和线性回归

如果你使用 Python 处理数据&#xff0c;你可能听说过 statsmodel 库。 Statsmodels 是一个 Python 模块&#xff0c;它提供各种统计模型和函数来探索、分析和可视化数据。该库广泛用于学术研究、金融和数据科学。 在本文中&#xff0c;我们将介绍 statsmodel 库的基础知识、如…...

设计模式——责任链模式

文章目录 责任链模式的定义场景示例责任链模式实现方案责任链模式扩展责任链模式的优缺点责任链模式在框架源码中的应用 责任链模式的定义 责任链模式又称职责链模式&#xff0c;是一种行为型设计模式。官方描述&#xff1a;使多个对象都有机会处理请求&#xff0c;从而避免请…...

nginx得if语句内proxy_pass不允许携带url部分,如何处理

在nginx中&#xff0c;proxy_pass指令不能直接携带URL部分。但是&#xff0c;可以使用rewrite指令结合正则表达式来处理URL部分。 下面是一个示例配置&#xff0c;演示如何使用rewrite指令将URL中的某个部分进行替换后传递给后端服务器&#xff1a; location /v100/{proxy_…...

CentOS7设置 redis 开机自启动

CentOS7设置 redis 开机自启动 步骤1.创建redis.service文件2.重新加载所有服务3.设置开机自启动4.自由地使用linux系统命令4.1.启动 Redis 服务4.2.查看 Redis 状态(-l:查看完整的信息)4.3.停止 Redis 服务4.4.重启 Redis 服务 步骤 如果你傲娇&#xff0c;不想拷贝&#xff0…...

C++虚函数(定义,作用,原理,案例)

一.定义&#xff1a; C的虚函数是在父类(基类)中声明的的函数&#xff0c;它可在子类(派生类)中重写。二.作用 虚函数的目的是实现多态性&#xff0c;即在程序运行时根据对象的实际类型确定调用哪个函数。三.使用方法&#xff1a; 在基类中声明虚函数时&#xff0c;需要在函…...

C#中.NET 6.0 控制台应用通过EF访问新建数据库

目录 一、 操作步骤 二、编写EF模型和数据库上下文 三、 移植&#xff08;Migrations&#xff09;数据库 四、编写应用程序并运行 前文已经说过.NET Framework4.8 控制台应用通过EF访问新建数据库&#xff0c;这里的数据据库要根据事先编写好的EF模型、经过一番操作&#x…...

conda创建pytorch环境报错

昨天训练数据的时候&#xff0c;发现Anaconda占用C盘达到了20G&#xff08;暑假在cmd状态下安装的&#xff0c;默认下载到了C盘&#xff09;&#xff0c;心道再创建几个环境&#xff0c;C盘就要爆红了&#xff0c;于是重装Anaconda到了D盘&#xff0c;不过之后的初始化并不顺利…...

数据结构-插入排序实现

文章目录 1、描述2、代码实现3、结果4、复杂度 1、描述 待排序的数组分为已排序、未排序两部分; 初始状态时&#xff0c;仅有第一个元素为已排序序列&#xff0c;第一个以外的元素为未排序序列&#xff1b; 此后遍历未排序序列&#xff0c; 将元素逐一插入到已排序的序列中&am…...

CGlib动态代理和JDK动态代理

CGlib代理模式是一种基于字节码操作的代理模式&#xff0c;它通过生成被代理类的子类来实现代理功能。 CGlib通过继承被代理类&#xff0c;生成一个代理类的子类&#xff0c;并重写父类的方法&#xff0c;在方法的前后插入相应的代理逻辑。这种方式不需要被代理类实现接口&…...

分类预测 | Matlab实现PSO-GRU-Attention粒子群算法优化门控循环单元融合注意力机制多特征分类预测

分类预测 | Matlab实现PSO-GRU-Attention粒子群算法优化门控循环单元融合注意力机制多特征分类预测 目录 分类预测 | Matlab实现PSO-GRU-Attention粒子群算法优化门控循环单元融合注意力机制多特征分类预测分类效果基本描述程序设计参考资料 分类效果 基本描述 1.Matlab实现PSO…...

Python OpenCV 视频抽帧处理并保存

上篇文章中基于OpenCV实现图像处理后&#xff0c;类似的&#xff0c;也可以对视频进行处理。OpenCV库可以将视频的每一帧读取出来&#xff0c;然后对每一帧图像做相应的操作&#xff0c;并保存成新的视频。 1. 读取视频&#xff0c;获取相关参数 import cv2 import numpy as…...

英伟达AI布局的新动向:H200 GPU开启生成式AI的新纪元

英伟达Nvidia是全球领先的AI计算平台和GPU制造商&#xff0c;近年来一直在不断推出创新的AI产品和解决方案&#xff0c;为各行各业的AI应用提供强大的支持。 最近&#xff0c;英伟达在GTC 2023大会上发布了一款专为训练和部署生成式AI模型的图形处理单元&#xff08;GPU&#…...

Windows11 python3.12 安装pyqt6 pyqt6-tools

Windows11 python3.12 安装pyqt6比较容易&#xff0c;但pyqt6-tools一直安装不上去。出错信息如下&#xff1a; (venv) PS D:\python_project\pyqt6> pip install pyqt6-tools Collecting pyqt6-toolsUsing cached pyqt6_tools-6.4.2.3.3-py3-none-any.whl (29 kB) Collec…...

反弹Shell

概述 反弹shell&#xff08;reverse shell&#xff09;就是控制端监听在某TCP/UDP端口&#xff0c;被控端发起请求到该端口&#xff0c;并将其命令行的输入输出转到控制端。reverse shell与telnet&#xff0c;ssh等标准shell对应&#xff0c;本质上是网络概念的客户端与服务端…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

高频面试之3Zookeeper

高频面试之3Zookeeper 文章目录 高频面试之3Zookeeper3.1 常用命令3.2 选举机制3.3 Zookeeper符合法则中哪两个&#xff1f;3.4 Zookeeper脑裂3.5 Zookeeper用来干嘛了 3.1 常用命令 ls、get、create、delete、deleteall3.2 选举机制 半数机制&#xff08;过半机制&#xff0…...

JAVA后端开发——多租户

数据隔离是多租户系统中的核心概念&#xff0c;确保一个租户&#xff08;在这个系统中可能是一个公司或一个独立的客户&#xff09;的数据对其他租户是不可见的。在 RuoYi 框架&#xff08;您当前项目所使用的基础框架&#xff09;中&#xff0c;这通常是通过在数据表中增加一个…...

视觉slam十四讲实践部分记录——ch2、ch3

ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)

一、OpenBCI_GUI 项目概述 &#xff08;一&#xff09;项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台&#xff0c;其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言&#xff0c;首次接触 OpenBCI 设备时&#xff0c;往…...

图解JavaScript原型:原型链及其分析 | JavaScript图解

​​ 忽略该图的细节&#xff08;如内存地址值没有用二进制&#xff09; 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么&#xff1a;保存在堆中一块区域&#xff0c;同时在栈中有一块区域保存其在堆中的地址&#xff08;也就是我们通常说的该变量指向谁&…...

聚六亚甲基单胍盐酸盐市场深度解析:现状、挑战与机遇

根据 QYResearch 发布的市场报告显示&#xff0c;全球市场规模预计在 2031 年达到 9848 万美元&#xff0c;2025 - 2031 年期间年复合增长率&#xff08;CAGR&#xff09;为 3.7%。在竞争格局上&#xff0c;市场集中度较高&#xff0c;2024 年全球前十强厂商占据约 74.0% 的市场…...

StarRocks 全面向量化执行引擎深度解析

StarRocks 全面向量化执行引擎深度解析 StarRocks 的向量化执行引擎是其高性能的核心设计&#xff0c;相比传统行式处理引擎&#xff08;如MySQL&#xff09;&#xff0c;性能可提升 5-10倍。以下是分层拆解&#xff1a; 1. 向量化 vs 传统行式处理 维度行式处理向量化处理数…...

CppCon 2015 学习:Simple, Extensible Pattern Matching in C++14

什么是 Pattern Matching&#xff08;模式匹配&#xff09; ❝ 模式匹配就是一种“描述式”的写法&#xff0c;不需要你手动判断、提取数据&#xff0c;而是直接描述你希望的数据结构是什么样子&#xff0c;系统自动判断并提取。❞ 你给的定义拆解&#xff1a; ✴ Instead of …...