作者在 2010-10-13 15:44:44 发布以下内容
消息队列就是一个消息的链表。可以把消息看作一个记录,具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向中按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读走消息。
①消息队列的创建与打开
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
int msgget(key_t key,int msgflg);
返回值:
– 如果成功,返回消息队列标识符
– 如果失败,则返回-1
在以下两种情况下,该调用将创建一个新的消息队列:
– 如果没有消息队列与健值key相对应,并且msgflg中包含了IPC_CREAT标志位;
– key参数为IPC_PRIVATE;(其值为0)
②向消息队列中发送消息
原型:
int msgsnd(int msqid,struct msgbuf* msgp,int msgsz,int msgflg);
参数含义:
–msqid参数是消息队列标识符,它是由系统调用msgget返回的;
–msgp参数是指向消息缓冲区的指针;
– 参数msgsz中包含的是消息的字节大小,但不包括消息类型的长度(4个字节);
– 参数msgflg可以设置为0(此时为忽略此参数),或者使用IPC_NOWAIT。
返回值:
– 如果成功,返回值为0;
– 如果失败,返回值为-1
③从消息队列接收消息
函数形式:
intmsgrcv(intmsqid,structmsgbuf* msgp,int msgsz,long mtype,int msgflg);
参数含义:
– 第一个参数用来指定将要读取消息的队列;
– 第二个参数代表要存储消息的消息缓冲区的地址;
– 第三个参数是消息缓冲区的长度,不包括mtype的长度,它可以按照如下的方法计算:
msgsz=sizeof(structmymsgbuf)-sizeof(long);
– 第四个参数是要从消息队列中读取的消息的类型。如果此参数的值为0,那么队列中最长时间的一条消息将返回,而不论其类型是什么
返回值:
– 如果成功,则返回复制到消息缓冲区的字节数。
– 如果失败,则返回-1。
④消息队列控制
函数形式:
int msgctl(int msgqid,int cmd,struct msqid_ds* buf);
返回值:
– 如果成功,返回值为0;
– 如果失败,返回值为-1
–cmd参数的取值:
– IPC_STAT 读取消息队列的数据结构msqid_ds,并将其存储在buf指定 的地址中。
– IPC_SET 设置消息队列的数据结构msqid_ds中的ipc_perm元素的值 。这个值取自buf参数。
–IPC_RMID 从系统内核中移走消息队列。
/*write.msg.c*/
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#define BUFSIZ 512
struct message
{
long msg_type;
char msg_text[BUFSIZ];
};
int main(void)
{
int qid;
key_t key;
int len;
struct message msg;
/*根据不同的路径和键值产生标准的key*/
if((key=ftok(".",'a'))==-1)
{
perror("ftok");
exit(1);
}
/*创建消息队列*/
if((qid=msgget(key,IPC_CREAT|0666))==-1)
{
perror("msgget");
exit(1);
}
printf("opened queue %d \n",qid);
while(1)
{
/*写消息队列*/
puts("Please enter the message to queue:");
if((fgets((&msg)->msg_text,BUFSIZ,stdin))==NULL)
{
puts("no message");
exit(1);
}
msg.msg_type=getpid();
printf("message: %s is sent!\n",(&msg)->msg_text);
len=strlen(msg.msg_text);
/*添加消息队列*/
if(msgsnd(qid,&msg,len,0)<0)
{
perror("message posted");
exit(1);
}
}
/*从系统内核中移走消息队列*/
if((msgctl(qid,IPC_RMID,NULL))<0)
{
perror("msgctl");
exit(1);
}
exit(0);
}
/*read_msg.c*/
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#define BUFSIZ 512
struct message
{
long msg_type;
char msg_text[BUFSIZ];
};
int main(void)
{
int qid;
key_t key;
int len;
struct message msg;
/*根据不同的路径和键值产生标准的key*/
if((key=ftok(".",'a'))==-1)
{
perror("ftok");
exit(1);
}
/*创建消息队列*/
if((qid=msgget(key,IPC_CREAT|0666))==-1)
{
perror("msgget");
exit(1);
}
printf("opened queue %d \n",qid);
while(1)
{
/*读取消息队列*/
if(msgrcv(qid,&msg,BUFSIZ,0,0)<0)
{
perror("msgrcv");
exit(1);
}
printf("message : %s is received!\n",(&msg)->msg_text);
}
/*从系统内核中移走消息队列*/
if((msgctl(qid,IPC_RMID,NULL))<0)
{
perror("msgctl");
exit(1);
}
exit(0);
}
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#define BUFSIZ 512
struct message
{
long msg_type;
char msg_text[BUFSIZ];
};
int main(void)
{
int qid;
key_t key;
int len;
struct message msg;
/*根据不同的路径和键值产生标准的key*/
if((key=ftok(".",'a'))==-1)
{
perror("ftok");
exit(1);
}
/*创建消息队列*/
if((qid=msgget(key,IPC_CREAT|0666))==-1)
{
perror("msgget");
exit(1);
}
printf("opened queue %d \n",qid);
while(1)
{
/*写消息队列*/
puts("Please enter the message to queue:");
if((fgets((&msg)->msg_text,BUFSIZ,stdin))==NULL)
{
puts("no message");
exit(1);
}
msg.msg_type=getpid();
printf("message: %s is sent!\n",(&msg)->msg_text);
len=strlen(msg.msg_text);
/*添加消息队列*/
if(msgsnd(qid,&msg,len,0)<0)
{
perror("message posted");
exit(1);
}
}
/*从系统内核中移走消息队列*/
if((msgctl(qid,IPC_RMID,NULL))<0)
{
perror("msgctl");
exit(1);
}
exit(0);
}
/*read_msg.c*/
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#define BUFSIZ 512
struct message
{
long msg_type;
char msg_text[BUFSIZ];
};
int main(void)
{
int qid;
key_t key;
int len;
struct message msg;
/*根据不同的路径和键值产生标准的key*/
if((key=ftok(".",'a'))==-1)
{
perror("ftok");
exit(1);
}
/*创建消息队列*/
if((qid=msgget(key,IPC_CREAT|0666))==-1)
{
perror("msgget");
exit(1);
}
printf("opened queue %d \n",qid);
while(1)
{
/*读取消息队列*/
if(msgrcv(qid,&msg,BUFSIZ,0,0)<0)
{
perror("msgrcv");
exit(1);
}
printf("message : %s is received!\n",(&msg)->msg_text);
}
/*从系统内核中移走消息队列*/
if((msgctl(qid,IPC_RMID,NULL))<0)
{
perror("msgctl");
exit(1);
}
exit(0);
}