C++ 中消息队列函数实例详解
C++中消息队列函数实例详解
1.消息队列结构体的定义
typedefstruct{
uid_tuid;/*owner`suserid*/
gid_tgid;/*owner`sgroupid*/
udi_tcuid;/*creator`suserid*/
gid_tcgid;/*creator`sgroupid*/
mode_tmode;/*read-writepermissions0400MSG_R0200MSG_W*/
ulong_tseq;/*slotusagesequencenumber*/
}ipc_perm;
typedefstuct{
structipc_permmsg_perm;/*read_writeperms*/
structmsg*msg_first;/*ptrtofirstmessageonqueue*/
structmsg*msg_last;/*ptrtolastmessageonqueue*/
msglen_tmsg_cbytes;/*usedbytescurrentonqueue*/
msgqnum_tmsg_qnum;/*currentnumofmessageonqueue*/
msglen_tmsg_qbytes;/*max#ofbytesallowedonqueue*/
pid_tmsg_lspid;/*pidoflastmsgsnd()*/
pid_tmsg_lrpid;/*pidoflastmsgrcv()*/
time_tmsg_stime;/*timeoflastmsgsnd()*/
time_tmsg_rtime;/*timeoflastmsgrcv()*/
time_tmsg_ctime;/*timeoflastmsgctl()*/
}msqid_ds;
typedefstruct
{
longmtype;
charmbuf[MSGLEN];
}Message;
2.创建消息队列:
/*************************************************** Function: intmsgget(ket_tkey,intoflag); Explain: createorviewamessagequeue Return: aintindetify Include: sys/msg.h introduction: oflag:0400msg_r 0200msg_w 0600msg_wr ipc_creat:NOexistandthencreataqueue exist:referenceaqueue ipc_creat|ipc_excl:NOexistandthencreataqueue exist:returnerror ****************************************************/ #include#include #include intMsgGet(intkey) { intret; ret=msgget(key,0600|IPC_CREAT); //ret=msgget(key,0600|IPC_CREAT|IPC_EXCL); if(ret<0) perror("creatmsgiderror"); printf("msgid=%d/n",ret); system("ipcs-q-iret"); returnret; } intmain(intargc,char*agrv[]) { intkey; printf("pleasseinputmsgkey:"); scanf("%d",&key); MsgGet(key); return0; }
3.向消息队列中发送消息msgsnd
/***********************************************************************************
Function:
intmsgsnd(intmsqid,constvoid*ptr,size_tlength,intflag)
Explain:
sendamessagetoaqueue
Return:
len:sendmessagelen;
Include:
sys/msg.h
Introduction:
flag:0:ifqueuefullwait:1>具备存放新消息的空间
2>由msqid标识的消息队列从系统中删除(返回EIDRM错误)
3>调用线程被某个捕获的信号所中断(返回EINTR错误)
IPC_NOWAIT:如果没有存放新消息的空间,函数马上返回
1>指定的队列中有太多的字节
2>在系统范围存在太多的消息
*****************************************************************************************/
#include"typemsg.h"
intMsgSnd(intmsqid,char*buf,intlen,intflag)
{
intret;
ret=msgsnd(msqid,buf,len,flag);
if(ret<0)
perror("msgsnderror");
system("ipcs-q");
returnret;
}
intmain()
{
intmsqid,len,stype;
Messagemsgb;
memset(&msgb,0,sizeof(Message));
printf("msgsnd:pleaseinputmsqid:");
scanf("%d",&msqid);
printf("pleaseinputmsgtype:");
scanf("%d",&stype);
msgb.mtype=stype;
strcpy(msgb.mbuf,"zhangweia");
MsgSnd(msqid,(char*)&msgb,sizeof(Message),0);
return0;
}
4.从队列中获取消息msgrcv
/********************************************************************* Function: intmsgrcv(intmsqid,constvoid*ptr,size_tmsglen,longtype,intflag) Explain: recvmessageorderbytype msgrcverror:Argumentlisttoolong-->msglen的长度小于消息体中消息的长度 Para: ptr:pointtomessagestruct msglen:由ptr指向的缓冲区中数据部分的大小,这个是该函数能够返回的最大数据量 type:messagetype; 1>0:返回队列中最早的消息 2>大于0:返回消息队列中类型为type的第一个消息 3>小于0:返回消息队列中类型小于或者等于type的绝对值的消息类型中最小的第一个消息 flag:0没有消息或者消息类型不符合的时候,线程等待 响应:1>有一个所请求类型的消息可以获取 2>msqid的消息队列被系统删除,返回一个EIDRM 3>调用线程被某个捕获的信号所中断 IPC_NOWAIT:在没有数据的情况下,立即返回一个ENOMSG错误 MSGNOERROR:当所接受的消息数据部分大于msglen长度时,获取截短的数据部分,否则返回E2BIG错误 Return: messagelen *********************************************************************/ #include"typemsg.h" intMsgRcv(intmsqid,char*buf,intmsglen,longtype,intflag) { intret; ret=msgrcv(msqid,buf,msglen,type,flag); if(ret<0) perror("msgrcverror"); system("ipcs-q"); returnret; } intmain() { intmsqid,len; longttype; Messagembuf; printf("msgrcv:pleaseinputrecvmsqid:"); scanf("%d",&msqid); MsgRcv(msqid,(char*)&mbuf,8900,0,IPC_NOWAIT); printf("recvmessage=%s/n",mbuf.mbuf); Put_String((unsignedchar*)&mbuf,sizeof(Message)); return0; }
6.消息队列的控制msgctl
/**********************************************************
Function:
intmsgctl(intmsqid,intcmd,structmsqid_ds*buff)
Explain:
cdm:IPC_RMID;deletemsqid
IPC_SET:
IPC_STAT:returnmsqidstat
*********************************************************/
#include"typemsg.h"
intMsgCtl(intmsqid,intcmd,structmsqid_ds*buff)
{
intret;
ret=msgctl(msqid,cmd,buff);
if(ret<0)
{
perror("msgctlerror");
return-1;
}
return0;
}
intmain()
{
intmsqid,type;
structmsqid_dsinfo;
printf("pleaseinputmsqid/nandtype(1:icp_rmid;2:ipc_stat)");
scanf("%d%d",&msqid,&type);
if(type==1)
{
MsgCtl(msqid,IPC_RMID,NULL);
printf("deletequeuesuccess:%d/n",msqid);
}elseif(type==2)
{
MsgCtl(msqid,IPC_STAT,&info);
printf("getqueuestat:%d/n",msqid);
}
return0;
}
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!