msgrcv函数
msgrcv()函數被用來從消息隊列中取出消息。它在linux/msg.h
中的定義是這樣的:
系統調用: msgrcv()
函數聲明: int msgrcv ( int msqid, struct msgbuf *msgp, int msgsz, long
mtype,
int msgflg )
返回值: Number of bytes copied into message buffer
-1 on error: errno = E2BIG (Message length is greater than
msgsz,
no MSG_NOERROR)
EACCES (No read permission)
EFAULT (Address pointed to by msgp is
invalid)
EIDRM (Queue was removed during
retrieval)
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)
函數的前三個參數和msgsnd()函數中對應的參數的含義是相同的。第四個參數mtype
指定了函數從隊列中所取的消息的類型。函數將從隊列中搜索類型與之匹配的消息并將之
返回。不過這里有一個例外。如果mtype 的值是零的話,函數將不做類型檢查而自動返回
隊列中的最舊的消息。
第五個參數依然是是控制函數行為的標志,取值可以是:
0,表示忽略;
IPC_NOWAIT,如果消息隊列為空,則返回一個ENOMSG,并將控制權交回調用函數
的進程。如果不指定這個參數,那么進程將被阻塞直到函數可以從隊列中得到符合條件的
消息為止。如果一個client 正在等待消息的時候隊列被刪除,EIDRM 就會被返回。如果進
程在阻塞等待過程中收到了系統的中斷信號,EINTR 就會被返回。
MSG_NOERROR,如果函數取得的消息長度大于msgsz,將只返回msgsz 長度的信息,
剩下的部分被丟棄了。如果不指定這個參數,E2BIG 將被返回,而消息則留在隊列中不被
取出。
當消息從隊列內取出后,相應的消息就從隊列中刪除了。
我們將開發一個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 的使用,它防止了阻塞
轉載于:https://www.cnblogs.com/wangchaoguo-li/archive/2012/11/07/2758506.html
總結
- 上一篇: Porter Stemming Algo
- 下一篇: ThinkPHP框架使用心得二 CURD