您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

多进程编程 - 消息队列

时间:2020-08-20 10:30:50  来源:  作者:

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

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

msgget系统调用

msgget系统调用创建一个消息队列,或者获取一个已有的消息队列。定义如下:

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

和semegt系统调用一下,key参数是一个键值,用来标识一个全局唯一的消息队列。

msgflg参数使用的含义与semget系统调用的sem_flags参数相同。

多进程编程 - 信号量

msgget成功时返回一个正整数值,它是消息队列u的标识符。msgget失败时返回-1,并设置errno。

如果msgget用于创建消息队列,则与之关联的内核数据结构msqid_ds将被创建并初始化,msqid_ds结构体的定义如下:

sturct msqid_ds
{
    struct ipc_perm msg_perm;   /*消息队列的操作权限*/
    time_t msg_stime;           /*最后一次调用msgsnd时间*/
    time_t msg_rtime;           /*最后一次调用msgrcv时间*/
    time_t msg_ctime;           /*最后一次被修改的时间*/
    unsigned long __msg_cbytes; /*消息队列中已有的字节数*/
    msgqnum_t msg_qnum;         /*消息队列中已有的消息数*/
    msglen_t msg_qbytes;        /*消息队列允许的最大字节数*/
    pid_t msg_lspid;            /*最后执行msgsnd的进程的PID*/
    pid_t msg_lrpid;            /*最后执行msgrcv的进程的PID*/
};

msgsnd系统调用

msgsnd系统调用把一条消息添加到消息队列中。定义如下:

#include <sys/msg.h>
int msgsnd(int msqid, const void* msg_ptr, size_t msg_sz, int msgflg);

msqid参数是由msgget调用返回的消息队列标识符

msg_ptr参数指向一个准备发送的消息,消息必须被定义为如下类型:

struct msgbuf
{
    long mtype; //消息类型
    char mtext[512]; //消息数据
};

其中:

  • mtype成员指定消息的类型,它必须是一个正整数。
  • mtext是消息数据

msg_sz参数是消息的数据部分(mtext)的长度。这个长度可以为0,表示没有数据。

msgflg参数空值msgsnd的行为,它通常仅支持IPC_NOWAIT标志,即非阻塞的方式发送消息。默认情况下,发送消息时如果消息队列满了,则msgsnd将阻塞。

若IPC_NOWAIT标志被指定,则msgsnd将立即返回并设置errno为EAGAIN。

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

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

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

  • 将msg_qnum加1
  • 将msg_lspid设置为调用进程的PID
  • 将msg_stime设置为当前的时间

msgrcv系统调用

msgrcv系统调用从消息队列中获取消息,定义如下:

#include <sys/msg.h>
int msgrcv(int msqid, void* msg_ptr, size_t msg_sz,long int msgtype, int msgflg);

msqid参数是由msgget调用返回的消息队列标识符

msg_ptr参数用于存储接受的消息,msg_sz参数指定的是消息数据部分的长度

msgtype参数指定接受何种类型的消息。有如下几种方式来指定消息类型:

  • msgtype等于0。读取消息中的第一个消息。
  • msgtype大于0。读取消息队列中第一个类型为msgtype(除非指定了标志MSG_EXCEPT)
  • msgtype小于0。读取消息队列中第一个类型比msgtype的绝对值小的消息。

参数msg空值msgrcv函数的行为。它可以是如下一些标志的按位或:

  • IPC_NOWAIT:如果消息队列中没有消息,则msgrcv调用立即返回并设置errno为ENOMSG
  • MSG_EXCEPT:如果msgtype大于0,则接受消息队列中第一个非msgtype类型的消息
  • MSG_NOERROR:如果消息数据部分的长度超过了msg_sz,就将它设置为EINTR

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

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

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

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

msgctl系统调用

msgctl系统调用控制消息队列的某些属性,定义如下:

#include <sys/msg.h>
int msgctl(int msqid, int command, struct msqid_ds * buf);

msqid参数是由msgget调用返回的共享内存标识符。command参数指定要执行的命令。msgctl支持的所有命令如下表:

多进程编程 - 消息队列

 

msgctl成功时的返回值取决于command参数,如上表所示。msgctl函数失败时返回-1并设置errno。



Tags:编程   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
1. 前言了解响应式编程,首先我们需要了解函数式操作和Stream的操作,下面我们简单的复习一下喽。1.1 常用函数式编程函数式接口中我们先来回顾一下Java中的函数式接口。常见的...【详细内容】
2022-07-15  Tags: 编程  点击:(1)  评论:(0)  加入收藏
1、让我们一起来看下吧,直接上图。 第一眼看到是不是觉得很高逼格,暗黑画风,这很大佬。其实它就是------AidLearning。一个运行在安卓平台的linux系统,而且还包含了许多非常强大...【详细内容】
2022-07-15  Tags: 编程  点击:(2)  评论:(0)  加入收藏
OSCS(开源软件供应链安全社区)推出免费的漏洞、投毒情报订阅服务,社区用户可通过机器人订阅情报信息:https://www.oscs1024.com/?src=wx背景概述黑客通常使用受感染的机器而不...【详细内容】
2022-07-11  Tags: 编程  点击:(6)  评论:(0)  加入收藏
安全研究人员警告说,黑客可以滥用在线编程学习平台来远程发起网络攻击、窃取数据并扫描易受攻击的设备,只需使用网络浏览器。至少有一个这样的平台,称为 DataCamp,允许威胁参与...【详细内容】
2022-07-10  Tags: 编程  点击:(5)  评论:(0)  加入收藏
今天给大家分享一篇C语言编码规范,可以从源头上规避掉很多bug,希望能对大家有所帮助。 01 最重要的规则编写代码时最重要的一条规则是:检查周围的代码并尝试模仿它。 作为维护...【详细内容】
2022-07-04  Tags: 编程  点击:(22)  评论:(0)  加入收藏
什么编程语言最好?这是个能让各路程序员吵翻天的话题,每种语言都有自己的拥趸,全球现在找出三五十种编程语言都不是问题,热门的至少也有20种,先不说这些语言好用与否,它们的性能也...【详细内容】
2022-07-01  Tags: 编程  点击:(29)  评论:(0)  加入收藏
什么是机器语言? 机器语言就是由二进制数字构成的程序,CPU 可以直接对其解释、执行。汇编语言、C 语言、Java、BASIC 等编程语言编写的程序,也都需要先转换成机器语言才能被执...【详细内容】
2022-06-30  Tags: 编程  点击:(26)  评论:(0)  加入收藏
转自:https://www.jdon.com/61280 本文分析了来自 5,508 个软件工程职位列表的数据,以帮助您找出哪些编程语言的薪水最高。 我们分析了RemoteOK(世界上最大的工作委员会)上 5k...【详细内容】
2022-06-30  Tags: 编程  点击:(27)  评论:(0)  加入收藏
在本课程中, 您将 详细、逐步地解释经典的精选 LeetCode 问题 ,您将了解解决技术编码面试问题的最佳方法。 这是我在准备面试时希望参加的课程。课程英文名:LeetCode in Java A...【详细内容】
2022-06-30  Tags: 编程  点击:(19)  评论:(0)  加入收藏
四个手机编程APP带你玩转编程!语言学习宝典C语言编译器C++编译器C语言编译器IDE...【详细内容】
2022-06-26  Tags: 编程  点击:(22)  评论:(0)  加入收藏
▌简易百科推荐
1. 前言了解响应式编程,首先我们需要了解函数式操作和Stream的操作,下面我们简单的复习一下喽。1.1 常用函数式编程函数式接口中我们先来回顾一下Java中的函数式接口。常见的...【详细内容】
2022-07-15  二哥学Java    Tags:编程   点击:(1)  评论:(0)  加入收藏
在本文中,我们将学习如何使用 Next.js、 Prisma、 Postgres 和 Fastify 构建一个 Full-stack 应用程序。在本文中,我们将学习如何使用 Next.js、 Prisma、 Postgres 和 Fastif...【详细内容】
2022-07-12  qaseven    Tags:全栈   点击:(9)  评论:(0)  加入收藏
好的软件开发网站有哪些?做软件开发哪些网站能提供帮助呢?这些很多做软件开发的小伙伴都会问到的问题。007出海全球社交流量导航网站,整合了多方出海跨境网站资源,为你介绍出海...【详细内容】
2022-07-08  Chuhai007    Tags:软件开发   点击:(10)  评论:(0)  加入收藏
我们用monkey做压力测试后,会保存一个monkey日志,那如果想快速的分析日志中有哪些异常,我们可以用批处理工具进行快速的筛查,我们一起来看看吧。先编写个小脚本,然后修改为bat后...【详细内容】
2022-07-08  溪流涌动    Tags:monkey   点击:(13)  评论:(0)  加入收藏
白盒测试落地实践分为两个大方向,一个是静态分析,一个是动态分析,当然啦,也可以叫做静态测试和动态测试。那我们如何高质量保效率的做好白盒测试呢?Parasoft已经为您准备好了成熟...【详细内容】
2022-07-08  Parasoft中国    Tags:白盒测试   点击:(11)  评论:(0)  加入收藏
Altium Designer 自带脚本功能的开发项目,可以调用官方AD API接口对原理图或者PCB进行自动操作,本文主要分享开发的流程,和一些基本的概念信息,本文介绍的脚本工具例子可以用在P...【详细内容】
2022-07-07  电子工程师伟哥    Tags:Altium Designer   点击:(21)  评论:(0)  加入收藏
一、目录介绍 前置知识点 NIO Netty 的核心组件 Channel Callback Future 和 Promise 事件和 ChannelHandler Hello World二、前置知识点1、NIO首先我们需要回顾一...【详细内容】
2022-07-06  架构师jickly    Tags:聊天系统   点击:(16)  评论:(0)  加入收藏
1.事件流事件流是对事件执行过程的描述,了解事件的执行过程有助于加深对事件的理解,提升开发实践中对事件运用的灵活度。2.捕获和冒泡捕获阶段是【从父到子】的传导过程,冒泡阶...【详细内容】
2022-07-06  金乾坤    Tags:API   点击:(13)  评论:(0)  加入收藏
刷盘策略CommitLog的asyncPutMessage方法中可以看到在写入消息之后,调用了submitFlushRequest方法执行刷盘策略:public class CommitLog { public CompletableFuture<PutMe...【详细内容】
2022-07-06  Java码农之路    Tags:RocketMQ   点击:(16)  评论:(0)  加入收藏
最近读了本好书-《深度学习推荐系统》,读完不觉全身通畅,于是就有了写这篇文章的想法,把自己的理解和总结分享给大家。 本文将按照从算法到工程的顺序,先介绍一下推荐系统整体...【详细内容】
2022-07-05  InfoQ    Tags:推荐系统   点击:(22)  评论:(0)  加入收藏
站内最新
站内热门
站内头条