文章目录
(一)消息队列
- 消息队列与有名管道相似
- 消息队列不需要管道的打开和关闭管道的操作
- 消息队列并未解决管道满时的阻塞问题
(1)消息队列原理
- 一个进程向另一个进程发送一个数据块(含有类型)
- 接收进程可以独立地接收不同类型的数据块
- 可以避免有名管道的同步和阻塞问题(未满状态)
- 可以查看紧急消息
- 每个数据块都有一个最大的长度限制(超出限制,消息队列函数失败的原因)
- 所有队列的所有数据块的总长度也有上限
(2)Linux系统下的两个宏定义:(其它系统未知)
- 一条消息的最大长度:MSGMAX
- 一个队列的最大长度:MSGMNB
(二)消息队列函数
(1)创建,访问一个消息队列
int msgget(key_t key, int msgflg);
- key : 键值,通过同一个键值来访问同一个消息队列(特殊键值IPC_PRIVATE,当前进程可用,私有队列没啥用)
- msgflg : 必须使用IPC_CREAT 和 | 按位或才能创建新的消息队列(没有则创建,已存在则忽略)
- 返回值 :成功返回队列标识符(正整数),失败-1
(2)添加消息到队列中
int msgsnd(int msqid, const void* msg_ptr, size_t msg_sz, int msgflg);
- msqid : msgget的返回的消息队列标识符
- msg_ptr : 是指向准备发送消息(数据块struct my_message{};)的指针
约束条件:
- 消息队列的长度小于系统规定的上限
- 必须以一个长整形long int 变量开始(作为接收函数区分类型的标准)
建议创建一个结构体类型:
struct my_message
{
long int message_type; //消息类型 > 0
... /*你希望传输的数据*/
}
- msg_sz : msg_ptr指向消息的长度(不包含类型的字节大小)
- msgflg : 控制此消息队列达到系统限制(队满),要发生的事。
(IPC_NOWAIT|函数不发送消息并立即返回-1)
队满情况下:如果没有请求类型的消息可用,且未指定IPC_NOWAIT,在MSGFLG中,调用过程被阻塞(等待系统的消息队列中腾出空间),直到下列条件之一:
- 所需类型的消息放置再队列中
- 消息队列被系统删除,系统调用失败,错误号设置为EIDRM
- 调用进程捕获一个信号。在这种情况下,系统调用失败将errno设置为EINTR。
- 返回值:成功返回0,失败-1
(3)从消息队列中获取消息
int msgrcv(int msaid, void* msg_ptr, size_t msg_sz, long int mstype, int msgflg);
- msqid : 是msgget返回的消息队列的标识符
- msg_ptr : 是一个指向准备接收消息的指针(struct my_message{long int , …};)
- msg_sz : 是接收消息的长度(不包括消息类型字节大小)
- msgtype : 是一个长整数,可以实现简单形式的优先级(优先级消息队列)
注意:
- msgtype为0,获取队列中第一个可用消息
- 大于0,获取同种类型的第一条消息
- 小于0,获取 小于或等于msgtype的绝对值的类型的第一条消息
<