msgsnd()函數 msgrcv()函數

來源:互聯網
上載者:User

msgsnd()函數

從函數名就可以看出,msgsnd()函數是用來向訊息佇列發送訊息的。在linux/msg.h 它
的函數定義是這樣的:
系統調用: msgsnd()
函式宣告: int msgsnd ( int msqid, struct msgbuf *msgp, int msgsz, int msgflg )
傳回值: 0 on success
-1 on error: errno = EAGAIN (queue is full, and IPC_NOWAIT was asserted)
EACCES (permission denied, no write permission)
EFAULT (msgp address isn't accessable – invalid)
EIDRM (The message queue has been removed)
EINTR (Received a signal while waiting to write)
EINVAL (Invalid message queue identifier, nonpositive
message type, or invalid message size)
ENOMEM (Not enough memory to copy message buffer)
傳給msgsnd()函數的第一個參數msqid 是訊息佇列對象的標識符(由msgget()函數得
到),第二個參數msgp 指向要發送的訊息所在的記憶體,第三個參數msgsz 是要發送資訊的
長度(位元組數),可以用以下的公式計算:
msgsz = sizeof(struct mymsgbuf) - sizeof(long);
第四個參數是控制函數行為的標誌,可以取以下的值:
0,忽略標誌位;
IPC_NOWAIT,如果訊息佇列已滿,訊息將不被寫入隊列,控制權返回調用函數的線
程。如果不指定這個參數,線程將被阻塞直到訊息被可以被寫入。
這裡我們將建立一個封裝函數來示範msgsnd()函數的使用:
int send_message( int qid, 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 = msgsnd( qid, qbuf, length, 0)) == -1)
{
return(-1);
}
return(result);

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 的使用,它防止了阻塞

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.