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; }
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!