System V 消息队列

  • 消息队列是半双工的通信方式

1.1 创建一个消息队列

  • 消息队列的特点:消息只能一条的读取,不能多读取,也不能少读取,每条消息有一个类型,可以按照消息的类型读取

  • 创建或者打开一条消息:

    /*************************
    函数功能:创建或者打开一条消息队列
    返回值: If successful, the return value will be the message queue identifier (anonnegative integer), otherwise -1 with errno indicating the error.
    *************************/
    #include <sys/types.h>
    #include <sys/ipc.h>
    include <sys/msg.h>
    int msgget(key_t key, int msgflg);
    /*参数
    key:键值,用来生成标识符
    msgflag:可以指定IPC_CREATE, IPC_EXCL等标记用 | 符号连接起来
    */
    
    1. 通过key值与指定的键值对应的队列匹配,如果匹配成功,返回既有队列的标识符,如果指定了IPC_CREATE, IPC_EXCL等标记,返回相关错误,如果没有匹配成功,但是指定了IPC_CREATE标记,创建一个新的消息队列对象

1.2 交换消息

  • 消息的常规形式

    struct mymsg
    {long mtype;       /*Message type*/char mtext;       /*Message body*/
    }
    /*这个结构可以由程序员自己决定,只是一般情况下的消息结构体是这样*/
    
  • 发送消息

    /*****************************
    函数功能:发送一条消息
    返回值: On failure both functions return -1 with errno  indicating  the  error,otherwise  msgsnd()  returns 0 and msgrcv() returns the number of bytesactually copied into the mtext array.
    *****************************/
    #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:消息队列的标识符
    msgp:指向一个消息结构
    msgsz:消息结构中消息本体的大小
    msgflg:位掩码的组合IPC_NOWAIT:执行一个非阻塞的发送操作,通常消息队列满的时候,msgsnd调用会阻塞,如果设置了这个标记,不会阻塞,会直接返回一个EINTR错误,并且该系统调用被打断之后,不会自动重启,就算设置了SA_RESETART标记
    */
    
  • 接受消息

    /*****************************
    函数功能:接受一条消息
    返回值: On failure both functions return -1 with errno  indicating  the  error,otherwise  msgsnd()  returns 0 and msgrcv() returns the number of bytesactually copied into the mtext array.
    *****************************/
    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/msg.h>
    ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
    /*参数:
    msqid:消息队列的标识符
    msgp:指向一个存放消息结构的缓冲区
    msgsz:指定了msgp指向的mtext字段(消息本体)最大能够容纳的大小,如果队列中消息大小超过这个字段,就不会从队列中读取消息,而是返回E2BIG错误
    msgtyp:消息的读取并非是先进先出,而是按照msgtype的类型进行选择性的读取
    1:msgtyp==0:删除队列中第一条消息,并且返回给调用进程
    2:msgtyp>0:将队列中第一个mtype等于msgtyp的消息删除并将其返回给调用进程,其它不相等不管,让它还是存在于队列中
    3:msgtyp<0:将等待队列中mtype值最小并且其值小于或者等于msgtyp的绝对值的第一条消息会被删除返回给调用进程
    msgflg:
    IPC_NOWAIT:执行一个非阻塞操作,没有匹配的消息类型,返回ENOMSG错误
    MSG_EXCEPT:当msgtyp>0时候,将队列中mtype不等于msgtyp的消息强制删除并且返回给调用者,这个标记linux特有的,需要定义_GNU_SOURCE之后才可以,等于msgtyp的消息忽略,让其存在于队列中
    MSG_NOERROR:如果消息中mtext字段大于msgsz,会截断mtext字段的数据大小为msgsz返回给调用者,截断剩余的数据会丢失,没有这个标志的话是不会发生截断的,而是直接报错
    */
    

1.3 消息队列控制操作

  • 函数功能:在标识符msqid的消息队列上执行控制操作

  • 返回值:Return 0 On success,or -1 on error

  • 函数原型:

    #include <sys/types.h>
    #include <sys/ipc.h>
    #include <sys/msg.h>
    int msgctl(int msqid, int cmd, struct msqid_ds *buf);
    
  • 参数:

    1. msqid:消息队列的标识符
    2. cmd:在消息队列上操作的相关命令
      1. IPC_RMID:立即删除消息队列对象及其关联的msqid_ds数据结构,队列中所有消息会丢失,所有被阻塞的读者和写者进程立即醒来,msgsnd和msgrcv会失败返回EIDRM,这个操作会忽略第三个参数
      2. IPC_STAT:将这个消息队列关联的msgid_ds数据结构的副本保存在buf指向的缓冲区
      3. IPC_SET:将buf指向的缓冲区提供的值更新这个消息队列关联的msqid_ds数据结构中的被选中的字段

1.4 消息队列关联数据结构

  • 每个icp对象的关联数据结构中共有的一部分:

    1. 该部分的讲解在第45章中已经完成,这里主要对消息队列关联数据结构独有的字段进行分析
  • 消息队列的关联数据结构

  1. msgqnum、msglen_t属于无符号整型
  2. msg_stime:队列创建之后,初始化为0,每次msgsnd调用会将这个字段设置为当前时间,新纪元到现在的秒数
  3. msg_stime:队列创建之后,初始化为0,每次msgsrcv调用会将这个字段设置为当前时间,新纪元到现在的秒数
  4. msg_ctime:队列创建之后,初始化为当前时间,每次IPC_SET操作会将这个字段设置为当前时间,新纪元到现在的秒数
  5. __msg_cbytes:队列创建之后,初始化为0,后续每个msgsnd或者msgsrcv调用都会把字段更新为队列中所有mtext字段包含的字节的总和
  6. msg_qnum:队列创建之后,初始化为0,后续每个msgsnd调用递增这个字段,后续每个msgrcv调用递减这个字段,以反映出队列中消息的总数
  7. msg_qbytes:这个字段为队列中所有消息的mtext字段包含的字节的总和设置了一个上限,队列创建之后,初始化为MSGMNB,特权进程可以使用IPC_SET操作更改该字段的值在0到INT_MAX之间,也可以在/proc/sys/kernel/msgmnb文件中做修改,以保证后续队列创建初始值以及非特权进程所能进行的修改
  8. msg_lspid:队列创建之后,初始化为0,后续每个msgsnd调用,会把该字段的值设置为调用进程的pid
  9. msg_lrpid:队列创建之后,初始化为0,后续每个msgrcv调用,会把该字段的值设置为调用进程的pid

1.5 消息队列的限制

  • 大多数UNIX实现会对System V消息队列操作施加各种各样的限制,比如系统级创建消息队列的数量、单条消息可以写入的字节数、一个消息队列一次最多可以保存的字节数、系统中消息队列能存放的消息总数,linux下可以在/proc/sys/kernel里面查看并且修改这些限制 ,具体可以查阅书籍本章节

1.6 使用消息队列实现客户端-服务器应用程序

  • 服务器和客户端之间可以采用一个消息队列,但是这里会存在一些问题:

    1. 注意区分消息类型,这里一般用进程ID作为消息类型
    2. 多个并行的写入可能会造成死锁等问题
  • 所以我们这里最好采用多个消息队列,每一个客户端一个,每一个服务器一个,但死锁的问题还是需要自己解决

1.7 使用System V 消息队列的缺点:

  • 优点:可以根据消息类型选择性的读取队列中的消息
  • 缺点:
    1. 消息队列的引用采用标识符,而不是文件描述符
    2. 使用键而不是文件名来标识消息队列会增加额外的程序设计复杂性
    3. 内核不会对使用消息队列的进程引用计数
    4. 消息队列有很多种限制
  • 总体上来讲最好避免使用System V 消息队列,应该尽量考虑其它方案,比如POSIX 消息队列,更加有难度的是基于多文件描述符的通信信道

System V 消息队列概念以及相关函数(msgget、msgsnd、msgrcv、msgctl)介绍相关推荐

  1. msgget();msgsnd();msgrcv();msgctl(); 消息队列 Linux进程间的通信方式之消息队列

    Linux进程间的通信方式 ----消息队列. 消息队列和共享内存类似 消息队列它允许一个或多个进程向它写消息,一个或多个进程向它写读消息. 消息队列存在于系统内核中,消息的数量受系统限制. 我们来看 ...

  2. 细说linux IPC(十):system V 消息队列

    [版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet 或 .../gentleliu,文章仅供学习交流,请勿用于商业用途] system V消息队列和posix消息队列类 ...

  3. 【Linux】system V 消息队列 | system V 信号量(简单赘述)

    文章目录 1 . system V 消息队列(了解) 接口 查看消息队列 2.system V 信号量 (了解) 1.进程互斥等概念的理解 2.认识信号量 3. 接口 这两部分主要是了解即可,为后面学 ...

  4. linux进程间通信:system V消息队列

    文章目录 基本介绍 编程接口 代码实例 消息队列的发送和接收 消息队列中的消息对象的属性控制 基本介绍 支持不同进程之间以消息(messages)的形式进行数据交换,消息能够拥有自己的标识,且内核使用 ...

  5. System V 消息队列

    一.System V 消息队列 有一个队列,队列存放各种消息.每个进程可以把数据封存在消息中,再放入队列.每个进程都可以拿到消息队列,再从中取出/放入消息. 消息队列也有管道一样的不足,就是每个消息的 ...

  6. System V消息队列

    简介 这篇笔记中介绍了消息队列的基本知识和Posix消息队列.这篇笔记主要学习记录System V消息队列,并对比两个消息队列. System V消息队列是更早的一个消息队列的实现.Posix消息队列 ...

  7. Linux网络编程之System V消息队列

    System V消息队列函数: #include<sys/types.h> #include<sys/ipc.h> #include<sys/msg.h> int ...

  8. (P26)system v消息队列:msgsnd函数 ,msgrcv函数

    文章目录 1.msgsnd函数 2.msgrcv函数 1.msgsnd函数 功能:把一条消息添加到消息队列中原型:int msgsnd(int msqid, const void *msgp, siz ...

  9. 06.System V 消息队列

    1.概述 System V消息队列使用消息队列标识符(message queue identifier)标识.具有足够特权的任何进程都可以往一个给定队列放置一个消息,具有足够特权的任何进程都可以从一个 ...

最新文章

  1. Android--添加子视图(addView和setView)
  2. rhel配置磁盘分区_rhel配置磁盘分区_centos系统三套硬盘分区方案[图文设置版]
  3. [原]零基础学习在Android进行SDL开发系列文章
  4. 前端面试题 微信小程序
  5. ubuntu14.04修改limits.conf后链接限制仍然不生效
  6. Security+ 学习笔记17 公钥基础设施
  7. USB速度异常的问题
  8. Protel99se基本教程 Protel 99SE从零开始学习教程视频教程
  9. 四、OSPF配置实验
  10. 学大伟业:如何利用课余时间学习物理竞赛,搞定自主招生?
  11. 用spark实现单词统计
  12. 武汉安全员ABC证报名条件有什么要求?甘建二
  13. 经历--比赛绿盟_安全研究员
  14. NYIST_ACM Ranking List FAQ
  15. H5+JavaScript 剪刀石头布小游戏完整代码
  16. Linux的网络测试命令(转载)
  17. 西门子消防主机FC18配套CAN光端机进行光纤冗余环网组网测试
  18. msr颜色复原matlab程序,Retinex 图像去模糊(含MATLAB代码)
  19. 浪潮服务器改uefi引导,关于windows系统的uefi启动方式,两种修复引导的方法
  20. bilibili如何空降

热门文章

  1. 2.1 reverse
  2. 东北林业大学计算机考研资料汇总
  3. Epub阅读器合集,建议收藏
  4. ES7、ES8、ES9、ES10、ES11、ES12、ES13、ES14(ES进阶之路二)
  5. 上海电力大学计算机考研资料汇总
  6. 你简历不写精通吗,你说怎么把Bean塞到Spring容器?
  7. 【三维装箱】基于粒子群算法求解三维装箱问题matlab源码
  8. sourcetree如何修改用户名
  9. android系统浏览器下载流程
  10. 拓扑关系——九交模型