消息队列相比于管道较为灵活,消息队列中将信息进行编号进行发送和接受。
消息队列函数
1.创建消息队列函数
int msgget(ket_t key,flag):
key可以自己随便创建数字,也可以通过系统分配给key,牢记key的类型是key_t 。
flag是标志符,一般可以是IPC_CREAT|0777。
返回值为消息队列标识符一般就取名msgpid。
2.读消息队列的消息
msgrcv(msgpid,结构体的指针,结构体,结构体大小直接用sizeof就好了,内容的标识符,0(表示默认))
3、使用msgctl()函数设置或获取消息队列属性:
int msgctl(int msgid,int cmd,struct msqid_ds* buf);
函数第1个参数为msgget()返回的消息队列标识符,第2个参数cmd为执行的控制操作,包括以下选项:
//from /usr/include/linux/ipc.h
#define IPC_RMID 0 // 立即删除消息队列
#define IPC_SET 1 // 设置buf中的消息队列属性
#define IPC_STAT 2 // 获取消息队列的属性并保存在buf中
#define IPC_INFO 3 // 获取限制信息
4、使用msgsnd()函数发送消息:
//from /usr/include/sys/msg.h
int msgsnd(int msgid,void* msg,size_t size,int msgflag);
函数第1个参数为消息队列标识符,第2个参数为用户定义的缓冲区,使用以下结构:
//from /usr/include/sys/msg.h
struct msgbuf
{
long mtype; //消息类型
char mtext[1]; //消息内容,可重新定义
};
第3个参数为接收消息的大小,第4个参数指定消息达到系统界限时,要采取的操作,一般取IPC_NOWAIT即如果需要等待,则函数立即返回错误。若设置为0,则表示函数将会一直阻塞。
5、使用msgrcv()函数接收消
int msgrcv(int msgid,void* msg,size_t size,long mtype,int msgflag);
函数参数同msgsnd()一样,只是多了一个mtype,表示要接收的消息队列类型。
以下是消息队列测试代码,起动两个进程,一个不断从终端读取数据并发送出去,另一个进程不断读取消息队列内容,并打印出来,方式均为非阻塞
msg_send.c
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/ipc.h>
#include <sys/msg.h>
typedef struct msg
{
int mtype;
char mtext[1024];
}MSG;
int main()
{
MSG msg;
key_t key;
int msgid = 0;
char sendbuf[1024];
struct msqid_ds buf;
memset(&buf,0,sizeof(struct msqid_ds));
memset(sendbuf,0,sizeof(sendbuf));
memset(&msg,0,sizeof(msg));
key = ftok("/tmp",'a');
msgid = msgget(key,0755|IPC_CREAT);创建消息队列
while(1)
{
memset(&msg,0,sizeof(MSG));
gets(msg.mtext);
msg.mtype = 10;
if(msgsnd(msgid,&msg,sizeof(msg),0))发送消息
{
printf("msgsnd fail\n");
exit(1);
}
}
return 0;
}
msg_recv.c
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <sys/time.h>
#include <sys/ipc.h>
#include <sys/msg.h>
typedef struct msg
{
int mtype;
char mtext[1024];
}MSG;
int main()
{
MSG msg;
key_t key;
int msgid = 0;
char sendbuf[1024];
struct msqid_ds buf;
memset(&buf,0,sizeof(struct msqid_ds));
memset(sendbuf,0,sizeof(sendbuf));
key = ftok("/tmp",'a');
msgid = msgget(key,0755|IPC_CREAT);打开消息队列
while(1)
{
memset(&msg,0,sizeof(msg));
msgrcv(msgid,&msg,sizeof(msg),11,0);接受消息
printf("mtype=%d,msgrcv = %s\n",msg.mtype,msg.mtext);
}
return 0;