系统调用msgsnd()的第一个参数是消息队列标识符,它是由系统调用msgget返回的。第二个参数是msgp,是指向消息缓冲区的指针。参数msgsz中包含的是消息的字节大小,但不包括消息类型的长度(4个字节)。 参数msgflg可以设置为0(此时为忽略此参数),或者使用IPC_NOWAIT。 如果消息队列已满,那么此消息则不会写入到消息队列中,控制将返回到调用进程中。如果没有指明,调用进程将会挂起,直到消息可以写入到队列中。 下面是一个发送消息的程序: intsend_message(int qid,struct mymsgbuf *qbuf) { intresult,length; /*The length is essentially the size of the structure minus sizeof(mtype)*/ length=sizeof(structmymsgbuf)-sizeof(long); if((result=msgsnd(qid,qbuf,length,0))==-1) { return(-1); } return(result); } 这个小程序试图将存储 在缓冲区qbuf中的消息发送到消息队列qid中。下面的程序是结合了上面两个程序的一个完整程序: #include<stdio.h> #include<stdlib.h> #include<linux/ipc.h> #include<linux/msg.h> main() { intqid; key_t msgkey; struct mymsgbuf{ longmtype;/*Message type*/ intrequest;/*Work request number*/ doublesalary;/*Employee's salary*/ }msg; /*Generateour IPC key value*/ msgkey=ftok(".",'m'); /*Open/createthequeue*/ if((qid=open_queue(msgkey))==-1){ perror("open_queue"); exit(1); } /*Load up the message with a r bitrary test data*/ msg.mtype=1;/*Messagetypemustbeapositivenumber!*/ msg.request=1;/*Dataelement#1*/ msg.salary=1000.00;/*Data element #2(my yearly salary!)*/ /*Bombsaway!*/ if((send_message(qid,&msg))==-1){ perror("send_message"); exit(1); } } 在创建和打开消息队列以后,我们将测试数据装入到消息缓冲区中。最后调用send_messag把消息发送到消息队列中。现在在消息队列中有了一条消息,我们可以使用ipcs命令来查看队列的状态。下面讨论如何从队列中获取消息。可以使用系统调用msgrcv(): [目录] -------------------------------------------------------------------------------- msgrcv() 系统调用:msgrcv(); 原型:intmsgrcv(intmsqid,structmsgbuf*msgp,intmsgsz,longmtype,intmsgflg); 返回值:如果成功,则返回复制到消息缓冲区的字节数。 如果失败,则返回-1:errno=E2BIG(消息的长度大于msgsz,没有MSG_NOERROR) EACCES(没有读的权限) EFAULT(msgp指向的地址是无效的) EIDRM(队列已经被删除) EINTR(被信号中断) EINVAL(msgqid无效,或者msgsz小于0) ENOMSG(使用IPC_NOWAIT,同时队列中的消息无法满足要求) 很明显,第一个参数用来指定将要读取消息的队列。第二个参数代表要存储消息的消息缓冲区的地址。第三个参数是消息缓冲区的长度,不包括mtype的长度,它可以按照如下的方法计算: msgsz=sizeof(structmymsgbuf)-sizeof(long); 第四个参数是要从消息队列中读取的消息的类型。如果此参数的值为0,那么队列中最长时间的一条消息将返回,而不论其类型是什么。 如果调用中使用了IPC_NOWAIT作为标志,那么当没有数据可以使用时,调用将把ENOMSG返回到调用进程中。否则,调用进程将会挂起,直到队列中的一条消息满足msgrcv()的参数要求。如果当客户端等待一条消息的时候队列为空,将会返回EIDRM。如果进程在等待消息的过程中捕捉到一个信号,则返回EINTR。 下面就是一个从队列中读取消息的程序: intread_message(int qid,long type,struct mymsgbuf*qbuf) { intresult,length; /*The length is essentially the size of the structure minus sizeof(mtype)*/ length=sizeof(structmymsgbuf)-sizeof(long); if((result=msgrcv(qid,qbuf,length,type,0))==-1) { return(-1); } return(result); } 在成功地读取了一条消息以后,队列中的这条消息的入口将被删除。 参数msgflg中的MSG_NOERROR位提供一种额外的用途。如果消息的实际长度大于msgsz,同时使用了MSG_NOERROR,那么消息将会被截断,只有与msgsz长度相等的消息返回。一般情况下,系统调用msgrcv()会返回-1,而这条消息将会继续保存在队列中。我们可以利用这个特点编制一个程序,利用这个程序可以查看消息队列的情况,看看符合我们条件的消息是否已经到来: intpeek_message(int qid,long type)
复制本页网址和标题,发送给你QQ/Msn的好友一起分享
上一篇:如何实现大图标风格的打开对话框
下一篇:ar和nm命令的使用