当前位置: 首页 > 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;本质上是网络概念的客户端与服务端…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

sqlserver 根据指定字符 解析拼接字符串

DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

12.找到字符串中所有字母异位词

&#x1f9e0; 题目解析 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义&#xff1a; 若两个字符串包含的字符种类和出现次数完全相同&#xff0c;顺序无所谓&#xff0c;则互为…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...