返回
Featured image of post 操作系统 —— 进程间通信之 SystemV 消息队列

操作系统 —— 进程间通信之 SystemV 消息队列

消息队列

  • 在新的应用程序中,不应再使用消息队列。【分布式系统里面,好像很常用!需要时再了解!】
    • 详见此 Readme 2.4 节
    • 若需要客户进程和服务器进程之间的双向数据流,用UNIX域套接字全双工管道
  • 队列:消息队列。信息的链接表,存储在内核中,由标识符标识。
  • 队列 ID:消息队列标识符。
  • 与队列关联的数据结构:定义队列的当前状态
struct msqid_ds {
    struct ipc_perm msg_perm;
    msgqnum_t       msg_qnum;       // 队列里的消息长度/数量
    msglen_t        msg_qbytes;     // 队列中能容纳的最大字节数
    pid_t           msg_lspid;      // 最后 msgsnd() 的 pid
    pid_t           msg_lrpid;      // 最后 msgrcv() 的 pid
    time_t          msg_stime;      // 最后 msgsnd() 的时间
    time_t          msg_rtime;      // 最后 msgrcv() 的时间
    time_t          msg_ctime;      // 最后改变时间
}

1. 消息队列的系统限制

  • 导出的:这种限制来源于其他限制。
    • 如:Linux 系统中,最大消息数受限于最大队列数,最大队列数受限于系统安装的 RAM 大小/数量。

2. 相关函数

  • key 转换标识符的规则,见Readme
  • 创建新队列、引用现有队列。
#include <sys/msg.h>

// key: 键
// 返回:标识符/队列 ID
int msgget(key_t key, int flag);
  • 队列控制函数
#include <sys/msg.h>
// cmd:
// * IPC_STAT: 取队列的 smqid_ds 结构,存放在 buf 中
// * IPC_SET: 将 buf 中的 msg_perm.uid/gid/mode/msg_qbytes 等复制到队列对应的 msqid_ds 结构中。
// * IPC_RMID: 删除队列及其中的所有数据,删除立即生效。
int msgctl(int msqid, int cmd, struct msqid_ds *buf)
  • 放数据到队列中
#include <sys/msg.h>

/*
 * msqid: 队列标识
 * ptr: 指向类似以下的结构
 *      * struct my_msg {
 *          long my_type;           // 数据类型【???】
 *          char my_test[nbytes];   // 数据
 *      }
 * nbytes: 数据大小
 * flag:
 *  * IPC_NOWAIT: 队列满,返回 -1,errno = EAGAIN
 *    * 否则,阻塞到
 *      * 等待到队列空;
 *      * 队列被删除,返回 -1, errno = EIDRM;
 *      * 收到信号,并从信号处理程序返回;返回 -1, errno = EINTR;
 */
int msgsnd(int msqid, const void *ptr, size_t nbytes, int flag);
  • 从队列中取数据
#include <sys/msg.h>

/*
 * type: 指定想要消息的类型。
 *  * type == 0: 队列中的第一个消息;
 *  * type > 0 : 队列中第一个类型为 type 的消息;
 *  * type < 0 : 返回队列中消息类型值<=`type 绝对值` 的消息。如果多个,则返回类型值最小的 [第一个] 消息。
 * flag:
 *  * IPC_NOWAIT: 队列空,立即返回 -1, errno = ENOMSG;
 *    * 否则,阻塞到
 *      * 等待到队列有需要的数据;
 *      * 队列被删除,返回 -1, errno = EIDRM;
 *      * 收到信号,并从信号处理程序返回;返回 -1, errno = EINTR;
 */
int msgrcv(int msqid, const void *ptr, size_t nbytes, long type, int flag);

3. 注意

  • 对于"在新的应用程序中,不应再使用消息队列",貌似现在很多系统还在使用,不确定是否说的是一个东西,需要时要再了解。

A.拓展

B. 参考

  • 《UNIX 环境高级编程 第三版》
相信美好的事情即将发生。
Built with Hugo
Theme Stack designed by Jimmy