📒
Notes
  • 个人笔记
  • Machine Learning
    • Tensorflow
      • Text
        • Keras构建RNN
        • 字词嵌入
        • 字词嵌入示例程序
      • Data processing
        • tf.data数据加载
      • Tensorflow Tricks
    • 循环神经网络概览
    • Pix2Pix
  • Assembly Language
    • DOS中的Debug模式
    • LOOP指令
    • 8086CPU
    • 标志位寄存器
    • 汇编指令
    • 汇编语言源程序格式
  • Linux System
    • Systemctl 服务脚本
    • Linux端口占用
    • Btrfs文件系统
    • C Socket网络编程细节问题
  • Hexo
    • Hexo下的Tag/Categories栏
    • Git备份博客
    • Hexo博客基本部署
  • Kernel
    • C语言中消息队列实现
    • Linux内核的进程调度函数
    • Linux内核模块的编译
    • Linux Kernel概述
  • Linux Software
    • Linux软件安装与配置
  • Docker
    • OVS+Docker网络构建
    • Docker分层垃圾清理
  • C
    • CMakeList语法
Powered by GitBook
On this page
  • POSIX消息队列
  • 建立:mq_open()
  • 消息队列的属性:mq_getattr()和mq_setattr()
  • 发送消息:mq_send()
  • 接收消息:mq_receive()
  • 消息队列的限制

Was this helpful?

  1. Kernel

C语言中消息队列实现

消息队列的实现包含了System V和POSIX两种版本,在接口上有一定的差异。

POSIX消息队列

POSIX消息队列对应的头文件为mqueue.h。

#include <mqueue.h>

建立:mq_open()

#include <fcntl.h>        /* For O_* constants */
#include <sys/stat.h>     /* For mode constants */
#include <mqueue.h>
mqd_t mq_open(const char *name, int oflag);
mqd_t mq_open(const char *name, int oflag, mode_t mode, struct mq_attr *attr);

参数 name:符合命名规则的消息队列名称。 oflag:代表打开的方式(读写模式等),以O_的形式给出。 mode和attr:可选,只有在oflag中含有O_CREAT标志且消息队列不存在时才需要。 *返回:所创建的消息队列(定义为mqd_t类型)。

oflag 以下为部分常用定义,详见Linux manual中的详细解释。

参数

操作

O_RDONLY

只读

O_WRONLY

只写

O_RDWR

可读可写

消息队列的属性:mq_getattr()和mq_setattr()

在Linux 2.6.18中,消息队列的属性被定义成如下结构体:

struct mq_attr
{
  long int mq_flags;    /* Message queue flags.  */
  long int mq_maxmsg;   /* Maximum number of messages.  */
  long int mq_msgsize;  /* Maximum message size.  */
  long int mq_curmsgs;  /* Number of messages currently queued.  */
  long int __pad[4];
};

对于属性的获取和设置可以通过下列两个函数完成:

#include <mqueue.h>
int mq_getattr(mqd_t mqdes, struct mq_attr *attr);
int mq_setattr(mqd_t mqdes, struct mq_attr *newattr, struct mq_attr *oldattr);

说明 mq_setattr唯一可以更改的属性是mq_flags,用于设置或清除消息队列的阻塞标志。其他的的值都不可以设置,会被忽略。 mq_maxmsg和mq_msgsize是在上面打开消息队列的时候设置的,队列创建后就不应该更改。而mq_curmsgs指示了消息数量,是随着运行自动变化的,也不应该被设置。 返回值:均为成功返回0,否则返回-1。

发送消息:mq_send()

int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio);

参数 mqdes:之前使用mq_open()建立的消息队列描述符。 msg_ptr:指向消息体缓冲区的指针。 msg_len:消息长度,不大于消息队列的mq_msgsize属性值(不然发送出去的消息可能存不下)。 msg_prio:消息的优先级,不大于最大优先级MQ_PRIO_MAX。

接收消息:mq_receive()

ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio);

参数 mag_len不能小于属性中的mq_msgsize,不然消息可能存不下。 其余的参数和mq_send()一致。 优先级 PISIX消息队列始终返回优先级最高、最早的消息,不在接收时指定优先级。

消息队列的限制

消息队列可以占用的存储空间被系统所限制,在到达一定容量后将无法发送消息。 如果设置消息队列属性时,将消息数和消息长度设置过大,会导致消息队列创建失败。

相关限制可以在shell中修改:

~$ ulimit -q 1024000000
~$ ulimit -a |grep message
POSIX message queues     (bytes, -q) 1024000000

另外还有MQ_OPEN_MAX限制单个进程能同时打开的消息队列数(PISIX保证至少为8),MQ_PRIO_MAX限制最大优先级。

PreviousKernelNextLinux内核的进程调度函数

Last updated 5 years ago

Was this helpful?