#include <sys/msg.h>
int main(void){
// 创建消息队列
// 通过key创建或获取消息队列 返回消息队列ID 失败返回-1
/*
* msgget 创建或获取消息队列
* key: ftok函数返回的key
* msgflg 标志位置
* 0 - 获取 不存在即失败(是否存在根据key来判断)
* IPC_CERAT - 创建 不存在即创建,已存在即获取(是否存在根据key来判断)
* IPC_EXCL - 排它 不存在即创建,已存在即失败(是否存在根据key来判断)
* */
// 表示创建权限为0664内存不获取旧的消息队列
// 发送消息
/*
* msgsnd 发送消息
* msgid int msgget获取的消息队列ID
* msgp void const* 指针,指向一块包含消息类型和消息数据的内存块,该内存的前4(如果是64为系统则是前8)个字节必须是一个大于0的整数,代表消息类型,其后紧跟消息数据v
* msgsz size_t 期望发送消息数据(不包含消息类型)的字节数
* msgflg int 发送标志(阻塞、非阻塞),一般取0
* 0 阻塞
* IPC_NOWAIT 非阻塞 当内核消息队列已达上线 会返回-1 并且errno 设置为EAGAIN
* */
// 接收消息
/*
* msgrcv 接收消息
* msgid int msgget获取的消息队列ID
* msgp void const* 指针,指向一块包含消息类型和消息数据的内存块,该内存的前4(如果是64为系统则是前8)个字节必须是一个大于0的整数,代表消息类型,其后紧跟消息数据v
* msgsz size_t 期望接收消息数据(不包含消息类型)的字节数
* msgtype long 消息数据的类型
* 0 默认。接收消息队列的第一条数据
* >0 如果msgflg参数不包含MSG_EXCEPT位,则提取消息队列第一条类型为msgtype的消息,如果msgflg参数包含MSG_EXCEPT位,则提取消息队列第一条类型不为msgtype的消息
* <0 提取消息队列中类型小于等于绝对值msgtype的消息,类型越小消息越被优先提取
* msgflg int 发送标志(阻塞、非阻塞),一般取0
* 0 阻塞
* IPC_NOWAIT 非阻塞 当内核消息队列已达上线 会返回-1 并且errno 设置为EAGAIN
* 注:
* 1.如果存在匹配类型的消息数据,但是数据长度大于msgsz,并且msgflg位包含MSG_NOERROR,则之截取msgsz数据剩余的直接丢弃,如果msgflg位不包含MSG_NOERROR,则不处理该消息,返回-1 并且errno 设置为E2BIG
* 2.如果存在匹配类型的消息数据,msgrcv函数会将消息移出消息队列,并返回所接收到消息数据的字节数,表示接收成功。
* 否则函数会阻塞,直到消息队列中有可接受的消息为止,如果msgflg位包含IPC_NOWAIT,则函数不会阻塞,而是返回-1,并且errno 设置为ENOMSG
*
* */
// 消息控制
/*
* msgctl
* msgid int msgget获取的消息队列ID
* cmd 要做的操作
* IPC_RMID 销毁共享内存
* buf NULL
* 成功返回0 失败返回-1
* 备注:调用销毁时,并非立即销毁,需要加载计数为0时才真正销毁;并且其他进程无法创建与这块共享内存的映射,之前已经创建的不受影响
* */
return 0;
}
#include <stdio.h>
#include <sys/msg.h>
#include <string.h>
int main(void) {
// 创建key
key_t key = ftok(".", 8);
// 创建消息队列
int msgid = msgget(key, IPC_CREAT | IPC_EXCL | 0664);
// 往消息队列中发送消息
for (;;) {
struct {
long msgType;
char msgData[128];
} msgBuf = {100, ""};
fgets(msgBuf.msgData, sizeof(msgBuf.msgData), stdin);
if (strcmp(msgBuf.msgData, "!\n") == 0) {
break;
}
if (msgsnd(msgid, &msgBuf, sizeof(msgBuf) - sizeof(msgBuf.msgType), 0) == -1) {
perror("msgsnd");
return -1;
}
}
// 销毁消息队列
if (msgctl(msgid, IPC_RMID, NULL) == -1) {
perror("msgctl");
return -1;
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/msg.h>
#include <string.h>
#include <errno.h>
int main(void) {
// 创建key
key_t key = ftok(".", 8);
// 获取消息队列
int msgid = msgget(key, 0);
// 接收消息
for (;;) {
struct {
long msgType;
char msgData[128];
} msgBuf = {100, ""};
if (msgrcv(msgid, &msgBuf, sizeof(msgBuf) - sizeof(msgBuf.msgType), 100, 0) == -1) {
if (errno == EIDRM) {
printf("消息队列关闭\n");
break;
} else {
perror("msgrcv");
return -1;
}
}
printf("msgType:%ld msgData:%s\n", msgBuf.msgType, msgBuf.msgData);
}
return 0;
}