声明:侵删
1.消息队列概述
消息队列是System V IPC对象的一种 存放在内存中由内核来维护
消息队列由消息队列ID来唯一标识
消息队列就是一个消息的链表。用户可以在消息队列中添加消息、读取消息
消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法,并且每一块数据块都有一个类型
消息队列可以按照类型来发送/接收消息
与管道一样,消息队列中数据被读取会删除 管道必须先进先出 而消息队列不用遵循
消息队列在内核中的表
消息队列使用步骤
①打开/创建消息队列 msgget
② 向消息队列发送消息 msgsnd
③从消息队列接收消息 msgrcv
④控制消息队列 msgctl
发送消息必须确定消息格式
通信双方首先定义好统一的消息格式
用户根据应用需求定义结构体类型
首成员类型为long,代表消息类型(正整数)
其他成员都属于消息正文
2.消息队列相关函数
打开创建消息队列 msgget函数
发送消息 msgsnd函数
接收消息 msgrcv函数
消息队列控制 msgctl函数
3.实例程序
消息发送端
/*msgsnd.c*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define IPC_PATH "/"
#define IPC_PRJ 1
#define MSG_TXT_SIZE 512
#define MSG_LEN sizeof(MSG)-sizeof(long)
typedef struct
{
long msg_type;
char msg_txt[MSG_TXT_SIZE];
}MSG;
int main()
{
key_t msg_key;
int msg_id;
MSG msg;
/*创建消息队列的KEY*/
if((msg_key = ftok(IPC_PATH,IPC_PRJ)) < 0)
{
perror("ftok");
exit(-1);
}
/*创建消息队列,获取消息队列ID*/
if ((msg_id = msgget(msg_key,IPC_CREAT|0666)) < 0)
{
perror("msgget");
exit(-1);
}
system("ipcs -q ");
/*获取终端输入信息,向消息队列发消息*/
while(1)
{
printf("Please Enter Message TO Queue\n");
if(fgets(msg.msg_txt,MSG_TXT_SIZE,stdin) < 0)
{
perror("fets");
exit(-1);
}
msg.msg_type = getpid(); /*将消息类型设置为当前进程ID*/
if(msgsnd(msg_id,&msg,MSG_LEN,0) < 0) /*堵塞*/
{
perror("msgsnd");
exit(-1);
}
if (strncmp(msg.msg_txt,"quit",4) == 0)
{
break;
}
}
/*删除消息队列*/
if(msgctl(msg_id,IPC_RMID,NULL) < 0 )
{
perror("msgctl");
exit(-1);
}
exit(0);
}
消息接收端
/*msgrcv.c*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define IPC_PATH "/"
#define IPC_PRJ 1
#define MSG_TXT_SIZE 512
#define MSG_LEN sizeof(MSG)-sizeof(long)
typedef struct
{
long msg_type;
char msg_txt[MSG_TXT_SIZE];
}MSG;
int main()
{
key_t msg_key;
int msg_id;
MSG msg; /*存放接收消息内容*/
/*创建消息队列的KEY*/
if((msg_key = ftok(IPC_PATH,IPC_PRJ)) < 0)
{
perror("ftok");
exit(-1);
}
/*创建消息队列,获取消息队列ID*/
if ((msg_id = msgget(msg_key,IPC_CREAT|0666)) < 0)
{
perror("msgget");
exit(-1);
}
system("ipcs -q "); /*获取消息队列消息,向终端打印*/
do
{
memset(msg.msg_txt,0,MSG_TXT_SIZE); /*将信号接收区清空*/
if (msgrcv(msg_id,&msg,MSG_TXT_SIZE,0,0) < 0 ) /*将类型设置为0
接收消息队列中的第一个消息
最后一个参数 0 堵塞模式*/
{
perror("msgrcv");
exit(-1);
}
printf("The message from process[%ld]:%s\n",msg.msg_type,msg.msg_txt);
} while (strncmp(msg.msg_txt,"quit",4) != 0);
system("ipcs -q");
printf("message queue was delete\n");
exit(0);
}
结果