Linux17 --- 消息队列

news2025/7/27 19:16:30

一、IPC进程间通信:消息队列

消息队列是在两个进程之间传递二进制块数据的一种简单有效的方式。每个数据块都有一个特定的类型,接收方可以根据类型来有选择地接收数据,而不一定像管道和命名管道那样必须以先进先出的方式接收数据。

Linux消息队列的API都定义在sys/msg.h头文件中,包括4个系统调用:msgget、msgsnd、msgrcv 和 msgctl。

在这里插入图片描述

1、相关系统调用:

1)msgget系统调用 – 创建或获取系统调用

msgget系统调用创建一个消息队列,或者获取一个已有的消息队列
其定义如下:
在这里插入图片描述
和semget系统调用一样,key参数是一个键值,用来标识一个全局唯一的消息队列。msgflg参数的使用和含义与semget系统调用的sem_flags参数相同。
msgget成功时返回一个正整数值,它是消息队列的标识符。msgget失败时返回-1,并设置errno。
如果msgget用于创建消息队列,则与之关联的内核数据结构msqid_ds将被创建并初始化。msqid_ds结构体的定义如下:
在这里插入图片描述

2)msgsnd 系统调用 – 添加到队列

msgsnd系统调用把一条消息添加到消息队列中。
其定义如下:
在这里插入图片描述
msqid 参数是由 msgget 调用返回的消息队列标识符。
msg_ptr 参数指向一个准备发送的消息,消息必须被定义为如下类型:
在这里插入图片描述
其中,mtype成员指定消息的类型,它必须是一个正整数。mtext是消息数据。msg_sz参数是消息的数据部分(mtext)的长度。这个长度可以为0,表示没有消息数据。
msgflg参数控制msgsnd的行为。它通常仅支持IPC_NOWAIT标志,即以非阻塞的方式发送消息。默认情况下,发送消息时如果消息队列满了,则msgsnd将阻塞。若IPCNOWAIT标志被指定,则msgsnd将立即返回并设置errno为EAGAIN。

处于阻塞状态的msgsnd调用可能被如下两种异常情况所中断:
1)消息队列被移除。此时msgsnd调用将立即返回并设置errno为EIDRM。
2)程序接收到信号。此时msgsnd调用将立即返回并设置errno为EINTR。
msgsnd成功时返回0,失败则返回-1并设置errno。msgsnd成功时将修改内核数据结构msqid_ds的部分字段,如下所示:
将msg_qnum 加1。
将msg_lspid 设置为调用进程的PID。
将msg_stime设置为当前的时间。

3)msgrcv 系统调用 – 获取消息

msgrcv系统调用从消息队列中获取消息。
其定义如下:
在这里插入图片描述
msqid参数是由msgget调用返回的消息队列标识符。
msg_ptr参数用于存储接收的消息,msg_sz参数指的是消息数据部分的长度。
msgtype参数指定接收何种类型的消息。我们可以使用如下几种方式来指定消息类型:

msgtype等于0。读取消息队列中的第一个消息。
msgtype大于0。读取消息队列中第一个类型为msgtype的	消息(除非指定了标志MSG_EXCEPT,见后文)。
msgtype小于0。读取消息队列中第一个类型值比msgtype		的绝对值小的消息。参数msgflg 控制msgrcv函数的行为。它	可以是如下一些标志的按位或:
IPC_NOWAIT。如果消息队列中没有消息,则msgrcv调用立即返回并设置errno为ENOMSG。
MSG_ EXCEPT。如果msgtype大于0,则接收消息队列中第一个非 msgtype类型的消息。
MSG NOERROR。如果消息数据部分的长度超过了msg_sz,就将它截断。

处于阻塞状态的msgrcv调用还可能被如下两种异常情况所中断:

消息队列被移除。此时msgrcv调用将立即返回并设置errno为EIDRM。
程序接收到信号。此时msgrcv调用将立即返回并设置errno为 EINTR。

msgrcv成功时返回0,失败则返回-1并设置errno。msgrcv成功时将修改内核数据结构msqid_ds的部分字段,如下所示:

将msg_qnum减1。
将msg_lrpid设置为调用进程的PID。
将msg_rtime设置为当前的时间。

4)msgctl – 控制某些属性

msgctl 系统调用控制消息队列的某些属性。
其定义如下:
在这里插入图片描述
msqid参数是由msgget调用返回的共享内存标识符。command参数指定要执行的命令。msgctl支持的所有命令如表13-4所示。
在这里插入图片描述
在这里插入图片描述
msgctl成功时的返回值取决于command参数,如表13-4所示。msgctl函数失败时返回-1并设置errno。

2、代码使用示例:

1)a.c --创建消息队列,并添加一个消息

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/msg.h>

//定义消息体
struct mess//由用户自己定义,只需要的一个成员为long type,长整形;代表消息类型。结构体名等都可自定义
{
    long type;
    char date[128];
};

int main()//创建消息队列,并添加一个消息
{
    int msgid = msgget((key_t)1235,IPC_CREAT|0600);//创建消息队列,IPC..为标志位,0600为权限
    
    if(msgid == -1)//判断是否创建成功
    {
        exit(0);
    }

    //添加消息
    //先定义一个结构体变量,用来表示消息
    struct mess dt;
    //给消息赋消息类型值
    dt.type = 1;//这里赋值为一号类型消息
    strcpy(dt.date,"hello1");//这里直接写入一个消息
    //将结构体添加到消息队列中
    msgsnd(msgid,(void *)&dt,128,0);//这里的128是数据部分的大小
}

其中4d3为1235,进程已经结束,但消息队列依旧存在。多次运行不会多次创建消息队列,但会多次写入数据。
在这里插入图片描述

2)b.c – 获取消息队列,并读取一个消息

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/msg.h>

//定义消息体
struct mess//由用户自己定义,只需要的一个成员为long type,长整形;代表消息类型。结构体名等都可自定义
{
    long type;
    char date[128];
};

int main()//获取消息队列,并读取一个消息
{
    int msgid = msgget((key_t)1235,IPC_CREAT|0600);//创建消息队列,IPC..为标志位,0600为权限
    
    if(msgid == -1)//判断是否创建成功
    {
        exit(0);
    }

    //读取消息
    //先定义一个结构体变量,用来表示消息
    struct mess dt;
    //获取消息
    msgrcv(msgid,(void*)&dt,128,1,0);//这里的128是消息部分的大小,不是结构体的大小
    printf("read:%s\n",dt.date);
    

}

每运行一次b,其就会从其所获取的消息队列中读取一个相对应信号类型的消息,如果没有,就会阻塞,等待另外进程写入,再读取。

msgrcv(msgid,(void*)&dt,128,1,0);

如果将第四个参数改为0,就回不区分消息类型,就会读取任意类型的消息。发送端不能发送0号类型消息,但接收端可以。

在这里插入图片描述

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

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

相关文章

BootStrap响应式项目实战之世界杯网页设计

BootStrap实战 目标 响应式布局复习 HTML5的复习 CSS3的复习 了解BootStrap 一.复习 响应式布局&#xff1a;页面可以随着设备的变化而动态改变。 ​ 淘宝&#xff1a;pc端一套页面&#xff1a;不能随着屏幕的缩小而变化&#xff1b; ​ 移动端&#xff1a;另外一套页面&am…

Java中的::

今天在练习SpringBoot的时候&#xff0c;看到了以下这种写法&#xff1a; //实体类&#xff1a; Data public class Book {private Integer id;private String type;private String name;private String description; }//测试类 //实现功能&#xff1a;关键字查询 Test void t…

PCB设计---深入浅出的反弹图

作者&#xff1a;一博科技高速先生成员 孙小兵 众所周知&#xff0c;信号的反射与互连线的阻抗密切相关&#xff0c;可以说互连线中阻抗突变是产生信号反射的最直接原因。但究竟为什么会发生反射&#xff0c;反射对信号的影响是什么样的&#xff0c;信号反射的过程又是如何呢&…

MySql死锁

MySql死锁产生的原因?[面试7.0] 高并发情况下,事务之间对资源的访问顺序交替会导致死锁 加锁失败且出现环时触发死锁 事务1事务2begin;select *from testlock where id1 for update;begin;select *from testlock where id2 for update;select *from testlock where id2 for…

安卓系统的启动

Init.rc启动 创建和挂在启动所需的文件目录初始化和启动属性服务解析init.rc配置文件并启动Ztgote进程 Zygote进程 创建一个Server端的Socket预加载类和资源启动SystemServer进程等待AMS请求创建新的应用程序进程 SystemServer进程 启动Binder线程池&#xff0c;这样就可以…

环保数采仪 VOCs|污染源|水质污染源|烟气排放在线监测

计讯物联环保数采仪&#xff0c;丰富接口&#xff0c;符合环保行业规约标准&#xff0c;具备采集、无线传输、控制、告警等功能&#xff0c;广泛应用于Vocs在线监测、水污染大气污染远程监测、烟气排放在线监控等场景&#xff0c;数据全方位多角度实时采集、自动上报、远程在线…

汽车倒车防碰撞报警系统的设计

目 录 1 绪论 1 1.1 背景 1 1.2 国外研究情况 1 1.3 超声波测距的优势 2 2 基本原理 3 2.1 超声波简介 3 2.2 超声波基本特性 4 2.3 超声波模块简介 5 2.4 超声波传感器原理 6 2.5 超声波的测距原理 6 3 总体方案 8 4 硬件实现 9 4.1 电路 9 4.1.1 主控制最小系统电路 10 4.1.…

面试24K字节测试开发岗被血虐,到底具有怎样的技术才算高级水平?

前几天我朋友跟我吐苦水&#xff0c;这波面试又把他打击到了&#xff0c;做了6年软件测试。。。 下面这条招聘是在腾讯招聘官网截图下来的&#xff0c;首先我们对高级水平下一个定义吧&#xff0c;那它应该是对标这个职级该有的能力 什么样的工程师才能算高级&#xff1f;至少…

《数据库的原理与应用》--用两种方法实现S-T数据库创建

一、实验目的 复习数据库的定义&#xff0c;用两种方法实现S-T数据库创建&#xff1b;用两种方法创建数据库表&#xff0c;最后为数据库中的三个表增加数据&#xff1b;分离数据库和备份数据库。数据库表为&#xff1a; 学生表&#xff1a;Student(Sno,Sname,Ssex,Sage,Sdept…

Django ORM 多表操作:一对一、一对多、多对多的增删改,基于对象/双下划线的跨表查询

Django model ORM数据表相关操作 分析思路&#xff0c;创建数据表 对于表操作&#xff0c;表之间的关联关系&#xff0c;必须理解他们之间的关系&#xff0c;对于编程很重要。可以看看映射关系、外键和relationship查询 &#xff0c;至少明白外键相关基本知识。 &#xff08…

App Languages 批量导入管理Android多语言文案

AppLanguages支持安卓的多语言文案管理啦&#xff0c;支持批量的检测&#xff0c;批量导入&#xff0c;批量删除&#xff0c;批量替换&#xff0c;批量导出。 操作界面 批量导入 1&#xff09;需要选择res文件夹的路径&#xff0c;方便创建和寻找本地的多语言文件 2&#xff…

ui界面的介绍

创建一个项目时默认选择带有ui界面&#xff0c;ui界面的作用是方便设计者设计功能。 ui界面常见的功能&#xff1a; 方便对象的创建&#xff0c;拖入到窗口中即可方便布局&#xff0c;可以直接使用布局对控件进行修饰方便制作信号&#xff0c;通过转到槽的机制&#xff0c;快速…

Cesium 入门(一)无服务 Cesium 环境

Cesium 入门&#xff08;一&#xff09;无服务环境 一、无服务环境下的 Cesium 无网络环境下的静态 cesium 地图服务&#xff0c;cesium 1.98.1 已经支持无 token 情况下的地图显示&#xff0c;默认 token 可用来展示 3d 地图&#xff0c;老版本 cesium&#xff0c;需自行前往…

Golang入门笔记(15)—— 数组

编程的世界中&#xff0c;或许是因为一次一次的定义变量&#xff0c;维护管理起来都太费劲了&#xff0c;所以推出了数组&#xff0c;将数据用数组的形式管理起来。 参考代码&#xff1a; package mainimport "fmt"func main() {var scores [5]intscores[0] 90sco…

RabbitMQ基础

文章目录一. Hello World二. Work Queues三. 消息应答1. 自动应答2. 手动应答3. 批量应答4. 消息自动重新入队四. 持久化1. 实现队列持久化2. 实现消息持久化五. 消息不公平分发1. 配置不公平分发2. 预取值六. 发布确认1. 发布确认原理2. 开启发布确认3. 单个发布确认4. 批量发…

DOM介绍及DOM获取元素的方式

1、DOM介绍 DOM&#xff08;Document Object Model&#xff09;&#xff1a;文档对象模型其实就是操作html中的标签的一些能力我们可以操作哪些内容○ 获取一个元素 ○ 移除一个元素 ○ 创建一个元素 ○ 向页面里面添加一个元素 ○ 给元素绑定一些事件 ○ 获取元素的属性 ○ …

Hive集群部署实验

目录一、实验介绍1.1 实验内容1.2 实验知识点1.3 实验环境1.4 实验资源1.5 实验步骤清单二、实训架构三、实验环境准备四、实验步骤4.1 Hive部署4.1.1 安装Hive4.1.3 修改hive配置文件4.1.4 创建Hadoop测试目录4.1.5 初始化hive元数据库4.2 Hive测试4.2.1 启动Hive4.2.2 创建测…

pytorch的gpu版本安装以及cpu版本的卸载

目录 前言 一、安装显卡驱动 二、安装Visual Studio 2019 三、安装CUDA 四、安装cudnn 五、安装anaconda 六、安装PyTorch 前言 因为最近需要导师的指导&#xff0c;我开始了unet的学习&#xff0c;虽然之前也学习过机器学习&#xff0c;但是只是浅尝辄止&#xff0c;没…

你好,以太坊社区,你准备好参加 ETH India 2022 黑客马拉松活动了吗

你好&#xff0c;以太坊社区&#xff0c;我们很高兴通过 ETH Global即将举行的ETH India 2022 黑客马拉松活动将Cartesi 技术带到亚洲&#xff01;如果你是一位喜欢探索尖端技术且是一位创新型开发人员&#xff0c;我们期待着你的到来&#xff0c;并且想帮助你将美好的DApps 发…

[BLIP]-多模态Language-Image预训练模型

论文&#xff1a;https://arxiv.org/pdf/2201.12086.pdf 代码&#xff1a;GitHub - salesforce/BLIP: PyTorch code for BLIP: Bootstrapping Language-Image Pre-training for Unified Vision-Language Understanding and Generation demo&#xff1a;BLIP - a Hugging Face …