消息队列——msgrcv()



功能:从消息队列中取出消息。

函数位置:linux/msg.h
函数原型: int msgrcv ( int msqid, struct msgbuf *msgp, int msgsz, long mtype, int msgflg )
返回值: 拷贝入message buffer的字节数(拷贝入msgsz中的字节数)

 -1 on error: errno = 

E2BIG (Message length is greater than msgsz,no MSG_NOERROR)
EACCES (No read permission)
EFAULT (Address pointed to by msgp isinvalid)
EIDRM (Queue was removed duringretrieval)
EINTR (Interrupted by arriving signal)
EINVAL (msgqid invalid, or msgsz less than 0)
ENOMSG (IPC_NOWAIT asserted, and no message exists in the queue to satisfy the request)

参数:

P1-int msqid:           消息队列的控制字(ID),用于区别各个消息队列,通过msgget函数获得,以消息队列的键值作为入参(具体键值可自定义)

P2-struct msgbuf *msgp: 指向消息缓冲区的指针,msgrcv中用于存放接收到的消息,msgsnd中用于存放要发送出的消息

P3-int msgsz:           消息的大小(字节数)

P4-long mtype:          值决定返回哪一条消息(等于0 --- 返回队列中最早的一条消息;大于0 --- 返回类型为mtype的第一条消息;小于0 --- 则返回其类型小于或等于mtype参数的绝对值的最小的一个消息)

P5-int msgflg:          是控制函数行为的标志,取值可以是:0,表示忽略;IPC_NOWAIT,如果消息队列为空,则返回一个ENOMSG,并将控制权交回调用函数
的进程。如果不指定这个参数,那么进程将被阻塞直到函数可以从队列中得到符合条件的消息为止。如果一个client 正在等待消息的时候队列被删除,EIDRM 就会被返回。如果进程在阻塞等待过程中收到了系统的中断信号,EINTR 就会被返回。MSG_NOERROR,如果函数取得的消息长度大于msgsz,将只返回msgsz 长度的信息,剩下的部分被丢弃了。如果不指定这个参数,E2BIG 将被返回,而消息则留在队列中不被取出。 

      

注:函数的前三个参数和msgsnd()函数中对应的参数的含义是相同的。第四个参数mtype指定了函数从队列中所取的消息的类型。函数将从队列中搜索类型与之匹配的消息并将之返回。不过这里有一个例外。如果mtype 的值是零的话,函数将不做类型检查而自动返回队列中的最旧的消息。

当消息从队列内取出后,相应的消息就从队列中删除了
我们将开发一个msgrcv()的封装函数read_message():
int read_message( int qid, long type, struct mymsgbuf *qbuf )
{
int result, length;
/* The length is essentially the size of the structure minus sizeof(mtype) */
length = sizeof(struct mymsgbuf) - sizeof(long);
if((result = msgrcv( qid, qbuf, length, type, 0)) == -1)
{
return(-1);
}
return(result);
}
利用上面提到的msgrcv()对消息长度的处理,我们可以使用下面的方法来检查队列内是存在符合条件的信息:
int peek_message( int qid, long type )
{
int result, length;
if((result = msgrcv( qid, NULL, 0, type, IPC_NOWAIT)) == -1)
{
if(errno == E2BIG)
return(TRUE);
}
return(FALSE);
}
这里我们将msgp 和msgsz 分别设为NULL 和零。然后检查函数的返回值,如果是E2BIG则说明存在符合指定类型的消息。一个要注意的地方是IPC_NOWAIT 的使用,它防止了阻塞

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值