操作步骤:
1.创建/打开消息队列
相关函数:
int msgget(key_t 键值,int 打开方式)
参数:键值 – 通过ftok()获取
打开方式:IPC_CREAT/0666
成功是凡是msgid 失败是返回-1
2.收消息/发消息
发送消息:
int msgsnd(int msgid,const void *msgp,size_t size,int flag)
int msgrecv(int msgid,const void *msgp,size_t size,int flag)
参数1: msgget 的返回值
size 消息的长度
flag: 0 表示没有数据时候会阻塞
msgp:需要自定义一个消息结构体,定义一个数据域和一个数据类型域的数据域。
返回值:收消息或者发消息的字节数。
注意,如果接收消息失败,并且原因是:检查接收消息的长度是不是比发送消息的长度小。
3.删除消息队列
删除消息队列:
int msgctl(int 消息队列的ID, int IPC_RMID,NULL)
消息队列和共享内存区别:
共享内存中的数据在读取之后还存在,
消息队列会在数据读取之后会消失。取消息:方式1:按照标记读取数据,方式2:按照顺序读取数据
创建或打开消息队列 msgget
添加消息 msgsnd
读取消息 msgrcv 可以按照类型吧消息从消息队列中取出
控制消息队列 msgctl 读取消息队列属性,并保存到buf指向缓冲区, 设置消息队列属性。从消 息中删除消息队列
消息队列发送
#include <stdio.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <string.h>
#include <sys/ipc.h>
#include <unistd.h>
#define SIZE 100
typedef struct msgBuf
{
long msgType;
char msgContent[SIZE];
}MSG;
int main(int argv,const char *argc[])
{
key_t keyRead = 0;
key_t keyWrite = 0;
int msgWriteID = 0;
int msgReadID = 0;
pid_t pid;
MSG msg;
int ret = 0;
//创建新的进程
pid = fork();
if(pid < 0)
{
perror("fork fail:");
return -1;
}
//创建并且打开消息队列-发送
keyWrite = ftok("/tmp", 11);
printf( "key=0x%x\r\n", keyWrite );
msgWriteID = msgget( keyWrite, IPC_CREAT | 0666 );
if ( msgWriteID < 0 )
{
perror("msg get error");
return -1;
}
printf("msgWriteID = %d\r\n", msgWriteID);
//创建消息队列 - 读操作
keyRead = ftok("/tmp",12);
printf("keyRead = %x\r\n",keyRead);
msgReadID = msgget(keyRead,IPC_CREAT|0666);
if(msgReadID < 0)
{
perror("msgReadID fail:");
return -1;
}
if(pid > 0)//父进程负责收消息
{
memset( &msg, 0, sizeof(msg) );
msg.msgType = 3;
strncpy( msg.msgContent , "AAAAAA", SIZE - 1 );
ret = msgsnd( msgWriteID, &msg, SIZE, 0);
if (ret < 0)
{
perror("msg snd error");
}
}else if(pid == 0)//子进程负责发送消息
{
//创建新的消息队列 - 发消息
memset( &msg, 0, sizeof(msg) );
gets(msg.msgContent);
msg.msgType = 3;
//strncpy( msg.msgContent , "AAAAAA", SIZE - 1 );
ret = msgsnd( msgWriteID, &msg, SIZE-20, 0);
if (ret < 0)
{
perror("msg snd error");
}
}
//删除消息队列
msgctl(msgReadID,IPC_RMID,NULL);
return 0;
}
消息队列接收
#include <stdio.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <string.h>
#include <sys/ipc.h>
#include <unistd.h>
#define SIZE 100
typedef struct msgBuf
{
long msgType;
char msgContent[SIZE];
}MSG;
int main(int argv,const char *argc[])
{
key_t keyRead = 0;
key_t keyWrite = 0;
int msgReadID = 0;
int msgWriteID = 0;
pid_t pid;
MSG msg;
int ret=0;
//创建新的进程
pid = fork();
if(pid < 0)
{
perror("fork Fail: ");
return -1;
}
//创建并且打开消息队列-读操作
keyRead = ftok("/tmp", 11);
printf( "keyRead = 0x%x\r\n", keyRead );
msgReadID = msgget( keyRead, IPC_CREAT | 0666 );
if ( msgReadID < 0 )
{
perror("msgReadID error");
return -1;
}
//创建并且打开新的队列消息-发送
keyWrite = ftok("/tmp",12);
printf("keyWrite = %x\r\n",keyWrite);
msgWriteID = msgget(keyWrite,IPC_CREAT|0666);
if(msgWriteID < 0)
{
perror("msgWriteID Fail: ");
return -1;
}
if(pid > 0)//父进程负责发消息
{
memset(&msg,0,sizeof(msg));
gets(msg.msgContent);
msg.msgType = 3;
ret = msgsnd(msgWriteID,&msg,SIZE-20,0);
if(ret < 0)
{
perror("msgsnd Fail:");
}
}else if(pid == 0)//子进程负责收消息
{
//收消息
memset(&msg, 0, sizeof(msg));
msg.msgType = 3;
if (0 > msgrcv(msgReadID, &msg, SIZE, msg.msgType , 0))
{
perror( "msg rcv error" );
}
else
{
printf("msg:%s\r\n", msg.msgContent);
}
}
//删除消息队列
msgctl ( msgReadID, IPC_RMID, NULL );
return 0;
}