目录
2.函数msgrcv在读取消息队列时,type参数有下面几种情况:
3.函数msgctl对消息队列进行操作时cmd常用的操作命令有
消息队列(Message Queue)是一种在进程间进行通信的机制,是消息的链接表,允许一个进程向另一个进程发送数据。消息队列是通过在内核中创建的一个消息缓冲区来实现的,允许多个进程向同一队列发送消息,并从中读取消息。
?// 创建或打开消息队列:成功返回队列ID,失败返回-1
1 int msgget(key_t key, int msgflg);
?// 写入消息:成功返回0,失败返回-1
2 int msgsnd(int msqid, const void *ptr, size_t size, int msgflg);
?// 读取消息:成功返回接收到的消息的字节数,失败返回-1
3 int msgrcv(int msqid, void *ptr, size_t size, long type,int msgflg);
?// 控制消息队列:成功返回0,失败返回-1
?4 int msgctl(int msqid, int cmd, struct msqid_ds *buf);
IPC_CREAT
一同使用时,如果消息队列已经存在,则返回错误。如果未指定 IPC_EXCL
,即使消息队列已经存在,也会返回其标识符。?当创建一个新的消息队列时,我们需要在标志位IPC_CREAT的后面或(|)上消息队列的访问权限,表示当key命名的消息队列不存在时创建一个消息队列,当key所命名的消息队列存在时则被忽略。
可以看出,type值非 0 时用于以非先进先出次序读消息。也可以把 type 看做优先级的权值
cmd
常用的操作命令有buf
中。buf
中提供的值。而参数buf
:指向 struct msqid_ds
结构体的指针,用于传递或接收消息队列的状态信息,当我们使用的是IPC_RMID时这里可以设置为空。
ftok
函数用于生成一个与文件路径名和项目 ID 相关的键值函数原型:key_t ftok(const char *pathname, int proj_id);
参数介绍:
pathname
:文件路径名,可以是一个现有的文件。通常选择一个存在的文件,因为ftok
使用文件的 inode 号和 proj_id 来生成键值。proj_id
:项目 ID,为整数。
ftok
函数通过将文件的 inode 号和项目 ID 整合在一起,产生一个唯一的键值。这个键值在 IPC 对象(例如消息队列、信号量、共享内存)的创建和访问中用于标识对象。
发送并接收
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
// 定义消息结构体
struct msgbuf {
long mtype; // 消息类型,必须大于 0
char mtext[128]; // 消息数据
int index; // 额外的索引信息
};
int main() {
// 通过 ftok 创建键值
key_t key = ftok(".", 5);
printf("key = %x\n", key);
// 创建或获取消息队列
int msqid = msgget(key, 0777 | IPC_CREAT);
if (msqid == -1) {
printf("msgget 失败!!!\n");
perror("why");
} else {
// 发送消息
struct msgbuf sendbuf = {88, "happy bay!!!", 88};
msgsnd(msqid, &sendbuf, strlen(sendbuf.mtext) + sizeof(sendbuf.index), 0);
// 接收消息
struct msgbuf rcvbuf;
msgrcv(msqid, &rcvbuf, sizeof(rcvbuf.mtext) + sizeof(rcvbuf.index), 100, 0);
printf("read: %s, index: %d\n", rcvbuf.mtext, rcvbuf.index);
}
// 删除消息队列
msgctl(key, IPC_RMID, NULL);
return 0;
}
接收并发送
#include <sys/types.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
// 定义消息结构体
struct msgbuf {
long mtype; // 消息类型,必须大于 0
char mtext[128]; // 消息数据
int index; // 额外的索引信息
};
int main() {
// 通过 ftok 创建键值
key_t key = ftok(".", 5);
printf("key = %x\n", key);
// 创建或获取消息队列
int msqid = msgget(key, 0777 | IPC_CREAT);
if (msqid == -1) {
printf("msgget 失败!!!\n");
perror("why");
} else {
// 接收消息
struct msgbuf rcvbuf;
msgrcv(msqid, &rcvbuf, sizeof(rcvbuf.mtext) + sizeof(rcvbuf.index), 88, 0);
printf("read: %s, index = %d\n", rcvbuf.mtext, rcvbuf.index);
// 发送消息
struct msgbuf sendbuf = {100, "thank you wjh !!!", 100};
msgsnd(msqid, &sendbuf, strlen(sendbuf.mtext) + sizeof(sendbuf.index), 0);
}
// 删除消息队列
msgctl(key, IPC_RMID, NULL);
return 0;
}