消息队列
定义:
作为通讯机制的一种,信号能够传送的信息量有限,而管道只能传送无格式的子节流,为了克服这些确定消息队列应运而生。消息队列是随内核持续的,只有在内核重启或人工删除时,该消息队列才会被删除。
键值:
每个消息队列在系统范围内都有唯一的键值与之对应,而键值获得两种方式:1:通过函数key_t ftok(char *pathname, char proj),通过文件名返回一个对应的键值。2:自己定义一个数字。
打开/创建:
int msgget(key_t key, int msgflag)
msgflag:标志位,以下方面:
1)IPC_CREAT:创建消息队列;
2)IPC_EXCL:与IPC_CREAT一同使用,表示如果创建的消息队列存在,则返回错误;
3)IPC_NOWAIT:读写消息队列无法满足要求时,不阻塞。
说明:在以下两种情况下会创建一个新的消息队列。
1)当key为IPC_PRIVATE,则函数创建一个新的消息队列;
2)当没有与键值对应的消息队列。
向消息队列发送消息:
struct msgbuf{
long mtype;
char mtext[1];
}
从消息队列获取消息:
设置及获得消息队列的属性,并删除消息。
举例说明:
功能:在一个进程内通过消息队列向进程写读数据。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define PATHNAME /home/smb/test/2-4-1/test.c
//#define BUFSIZ 20
struct msg_st
{
long int msg_type;
char some_text[BUFSIZ];
};
int open_queue(key_t key_val)
{
int qid;
qid = msgget(key_val,0666 | IPC_CREAT);
if(qid==-1)
{
return -1;
}
return (qid);
}
int write_messge(int qid, struct msg_st *qbuff)
{
int result,lens;
lens = sizeof(struct msg_st)-sizeof(long);
result = msgsnd(qid, qbuff, lens, IPC_NOWAIT);
if(result == -1)
{
return -1;
}
return (result);
}
int read_messge(int qid, struct msg_st *qbuff, long type)
{
int result,lens;
lens = sizeof(struct msg_st)-sizeof(long);
result = msgrcv(qid, qbuff,lens,type,0);
if(result == -1)
{
return -1;
}
return (result);
}
int main(void)
{
key_t key;
int msqid;
struct msg_st my_data;
int err = 0;
key = ftok("PATHNAME",'a');
printf("key=%d\n",key);
/*创建消息队列*/
msqid = open_queue(key);
if(msqid == -1)
{
fprintf(stderr,"msgget failed with error: %d\n",errno);
exit(EXIT_FAILURE);
}
/*初始化消息*/
my_data.msg_type = 1;
printf("please input messge to send=\n");
fgets(my_data.some_text, BUFSIZ,stdin);
/*发送消息到消息队列*/
err = write_messge(msqid, &my_data);
if(err == -1)
{
fprintf(stderr,"msg send fail\n");
exit(EXIT_FAILURE);
}
printf("send msg=%s\n",my_data.some_text);
memset(&my_data, 0, sizeof(struct msg_st));
err = read_messge(msqid, &my_data,1);
if(err == -1)
{
fprintf(stderr,"msg send fail\n");
exit(EXIT_FAILURE);
}
printf("recv msg=%s\n",my_data.some_text);
}
运行结果