消息队列
- 在新的应用程序中,不应再使用消息队列。【分布式系统里面,好像很常用!需要时再了解!】
- 队列:消息队列。信息的链接表,存储在内核中,由标识符标识。
- 队列 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. 参考