文章目录
1.概念
- 消息队列是一种进程间通信 (IPC) 机制,允许进程之间交换数据。
- 每个消息队列都有一个唯一的标识符 (msqid),通过该标识符来访问消息队列。
- 消息队列可以存储多个消息,每个消息包含消息类型和消息内容。
2. 创建消息队列
- 使用
msgget()
函数创建消息队列。 msgget()
函数需要两个参数:
int msgget(key_t key, int msgflag)
key_t key
: 消息队列的键值,用于标识消息队列。
int msgflg
: 控制消息队列的创建方式,例如IPC_CREAT
用于创建新的消息队列,IPC_EXCL
用于检查消息队列是否存在。- 成功创建或访问消息队列,返回正整数 或 为0消息队列标识符(ID)。
失败返回 < 0。
使用 IPC_PRIVATE 创建的每个消息队列都是唯一的,即使是同一个进程多次创建,它们之间也是相互独立的,不会共享数据。
IPC_PRIVATE
用于创建一个私有的消息队列,它只对创建它的进程可见,其他进程无法访问。并且当创建者进程终止时,该 IPC 对象也会被自动销毁。- 当一个进程使用
IPC_PRIVATE
创建消息队列时,系统会分配一个唯一的标识符(即消息队列 ID)给它。 - 即使同一个进程多次使用
IPC_PRIVATE
创建消息队列,每次分配的标识符也会是不同的。
因此,即使是同一个进程,每次使用 IPC_PRIVATE 创建的队列都是独立的、不同的消息队列。
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
int msqid1 = msgget(IPC_PRIVATE, IPC_CREAT | 0666);
if (msqid1 == -1) {
perror("msgget 1");
exit(1);
}
printf("Message queue ID 1: %d\n", msqid1);
int msqid2 = msgget(IPC_PRIVATE, IPC_CREAT | 0666);
if (msqid2 == -1) {
perror("msgget 2");
exit(1);
}
printf("Message queue ID 2: %d\n", msqid2);
// msqid1 和 msqid2 不同,指向不同的消息队列
if (msqid1 == msqid2) {
printf("Error: msqid1 and msqid2 are the same!\n");
} else {
printf("msqid1 and msqid2 are different, as expected.\n");
}
// 删除消息队列
msgctl(msqid1, IPC_RMID, NULL);
msgctl(msqid2, IPC_RMID, NULL);
return 0;
}
3. 发送消息
-
使用 msgsnd() 函数发送消息到消息队列。
-
msgsnd()
函数需要四个参数:
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
int msqid
: 消息队列标识符。
const void *msgp
: 指向消息结构体的指针。
size_t msgsz
: 消息结构体的大小。
int msgflg
: 控制消息发送方式,例如IPC_NOWAIT
用于非阻塞发送,填0
则用于阻塞发送。 -
返回值是 0 表示发送成功,-1 表示发送失败。