目录
(1)获取消息队列的ID(类似文件的描述符)(msgget)
1、管道的缺点
(1)无法读取一个“指定”的数据,因为数据没有标记,故只能按次序挨个读取
(2)多对进程之间的相互通信,要用多对管道分别处理
2、消息队列
(1)有数据标识的特殊管道,每一段被写入的数据都变成带标识的消息。
(2)读取消息的进程只要指定标识就可以正确读取,而不会受到其他消息干扰
(3)从运行效果看,一个带标识的消息队列,就像多条并存的管道
3、消息队列的API
(1)获取消息队列的ID(类似文件的描述符)(msgget)
(2)发送、接收消息(msgrcv)
a、发送消息时,消息必须被组织成以下形式
struct msgbuf
{
long mtype; // 消息的标识
char mtext[1]; // 消息的正文 可以是任何类型数据
};
发送出去的消息必须以一个 long 型数据打头,作为该消息的标识,后面的数据则没有要求。
b、消息的标识可以是任意长整型数值,但不能是 0L。
c、参数 msgsz 是消息中正文的大小,不包含消息的标识。
(3)获取和设置消息队列的属性(msgctl)
4、消息队列的使用方法
(1)发送者
A) 获取消息队列的 ID
B) 将数据放入一个附带有标识的特殊的结构体,发送给消息队列。
#include <sys/types.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <sys/msg.h>
struct msgbuf
{
long mtype; // 【重点】消息的标识
int num ; // 消息的正文 可以是任何类型数据
};
int main(int argc, char const *argv[])
{
// 获得KEY值
key_t key = ftok("./", 1 );
printf("key:%d\n" , key );
// 获得消息队列的ID
int ID = msgget( key , IPC_CREAT | 0644 );
printf("消息队列ID 为:%d \n " , ID );
// 配置消息
struct msgbuf msg = {
.mtype = 'X', // 设置消息数据的类型(标识)
.num = 1024 // 实际发送的信息
};
// 发送消息
msgsnd(ID , &msg , sizeof(msg.num), MSG_NOERROR);
// 标记删除
msgctl(ID , IPC_RMID , NULL );
return 0;
}
(2)接收者
A) 获取消息队列的 ID
B) 将指定标识的消息读出。
#include <sys/types.h>
#include <sys/ipc.h>
#include <stdio.h>
#include <sys/msg.h>
struct msgbuf
{
long mtype; // 【重点】消息的标识
int num ; // 消息的正文 可以是任何类型数据
};
int main(int argc, char const *argv[])
{
// 获得KEY值
key_t key = ftok("./", 1 );
printf("key:%d\n" , key );
// 获得消息队列的ID
int ID = msgget( key , IPC_CREAT | 0644 );
printf("消息队列ID 为:%d \n " , ID );
// 配置消息
struct msgbuf msg = {0};
// 接收消息
// int msg ;
int ret_val = msgrcv( ID , &msg, sizeof(msg.num), 'X', MSG_NOERROR );
printf("ret:%d msg:%d\n" , ret_val, msg.num );
// 标记删除
msgctl(ID , IPC_RMID , NULL );
return 0;
}