msgop() - Unix,Linux 系統呼叫 - 技術教學
Tutorials Point


  Unix 初學者指南
  Unix Shell 程式設計
  高階 Unix
  Unix 有用參考
  Unix 有用資源
  精選閱讀

版權所有 © 2014 tutorialspoint



  首頁     參考     討論論壇     關於 TP  

msgop() - Unix,Linux 系統呼叫


previous next AddThis Social Bookmark Button

廣告

名稱

msgop - 訊息操作

語法

 
#include <sys/types.h>

#include <sys/ipc.h>
#include <sys/msg.h>

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);

描述

msgsnd() 和 msgrcv() 系統呼叫分別用於向訊息佇列傳送訊息和從訊息佇列接收訊息。呼叫程序必須對訊息佇列具有寫許可權才能傳送訊息,並具有讀許可權才能接收訊息。

msgp 引數是指向呼叫者定義的結構體的指標,該結構體具有以下通用形式


        struct msgbuf {

                long    mtype;   /* 訊息型別,必須大於 0 */

                char    mtext[1];        /* 訊息資料 */

        };

mtext 欄位是一個數組(或其他結構體),其大小由 msgsz 指定,msgsz 是一個非負整數。允許零長度的訊息(即沒有 mtext 欄位)。mtype 欄位必須具有嚴格的正整數。接收程序可以使用此值進行訊息選擇(請參閱下面 msgrcv() 的描述)。

msgsnd() 系統呼叫將 msgp 指向的訊息副本追加到其識別符號由 msqid 指定的訊息佇列中。

如果佇列中有足夠的可用空間,msgsnd() 會立即成功。(佇列容量由訊息佇列關聯資料結構中的 msg_bytes 欄位定義。在建立佇列期間,此欄位初始化為 MSGMNB 位元組,但可以使用 msgctl() 修改此限制。)如果佇列中沒有足夠的可用空間,則 msgsnd() 的預設行為是阻塞,直到有空間可用為止。如果在 msgflg 中指定了 IPC_NOWAIT,則呼叫改為失敗,並出現 EAGAIN 錯誤。

如果佇列被刪除(在這種情況下,系統呼叫失敗,errno 設定為 EIDRM),或者捕獲到訊號(在這種情況下,系統呼叫失敗,errno 設定為 EINTR),則被阻塞的 msgsnd() 呼叫也可能失敗。(無論在建立訊號處理程式時 SA_RESTART 標誌的設定如何,msgsndmsgrcv 永遠不會在被訊號處理程式中斷後自動重新啟動。)

成功完成時,訊息佇列資料結構將按如下方式更新

標籤描述
msg_lspid 設定為呼叫程序的程序 ID。
msg_qnum 增加 1。
msg_stime 設定為當前時間。
系統呼叫 msgrcv() 從 msqid 指定的佇列中刪除一條訊息,並將其放入 msgp 指向的緩衝區中。
引數 msgsz 指定 msgp 引數指向的結構體的成員 mtext 的最大大小(以位元組為單位)。如果訊息文字的長度大於 msgsz,則行為取決於 msgflg 中是否指定了 MSG_NOERROR。如果指定了 MSG_NOERROR,則訊息文字將被截斷(並且截斷的部分將丟失);如果未指定 MSG_NOERROR,則訊息不會從佇列中刪除,並且系統呼叫失敗並返回 -1,errno 設定為 E2BIG
引數 msgtyp 指定請求的訊息型別,如下所示
如果 msgtyp 為 0,則讀取佇列中的第一條訊息。
如果 msgtyp 大於 0,則讀取佇列中型別為 msgtyp 的第一條訊息,除非在 msgflg 中指定了 MSG_EXCEPT,在這種情況下,將讀取佇列中型別不等於 msgtyp 的第一條訊息。
如果 msgtyp 小於 0,則讀取佇列中型別小於或等於 msgtyp 的絕對值的最小的第一條訊息。
msgflg 引數是一個位掩碼,透過將以下標誌中的零個或多個按位或運算構造而成
IPC_NOWAIT
 如果佇列中沒有請求型別的訊息,則立即返回。系統呼叫失敗,errno 設定為 ENOMSG
MSG_EXCEPT
 msgtyp 大於 0 結合使用,以讀取佇列中訊息型別與 msgtyp 不同的第一條訊息。
MSG_NOERROR
 如果訊息文字長度超過 msgsz 位元組,則將其截斷。
如果所需的型別的訊息不可用,並且在 msgflg 中未指定 IPC_NOWAIT,則呼叫程序將被阻塞,直到以下條件之一發生
將所需型別的訊息放入佇列中。
從系統中刪除訊息佇列。在這種情況下,系統呼叫失敗,errno 設定為 EIDRM
呼叫程序捕獲訊號。在這種情況下,系統呼叫失敗,errno 設定為 EINTR
成功完成時,訊息佇列資料結構將按如下方式更新
msg_lrpid 設定為呼叫程序的程序 ID。
msg_qnum 減 1。
msg_rtime 設定為當前時間。

返回值

如果失敗,則兩個函式都返回 -1,errno 指示錯誤,否則 msgsnd() 返回 0,而 msgrcv() 返回實際複製到 mtext 陣列中的位元組數。

錯誤

msgsnd() 失敗時,errno 將設定為以下值之一
標籤描述
EACCES 呼叫程序對訊息佇列沒有寫許可權,並且沒有 CAP_IPC_OWNER 功能。
EAGAIN 由於佇列的 msg_qbytes 限制,無法傳送訊息,並且在 msgflg 中指定了 IPC_NOWAIT
EFAULT msgp 指向的地址無法訪問。
EIDRM 訊息佇列已刪除。
EINTR 在滿訊息佇列條件下休眠時,程序捕獲到訊號。
EINVAL 無效的 msqid 值,或非正數的 mtype 值,或無效的 msgsz 值(小於 0 或大於系統值 MSGMAX)。
ENOMEM 系統沒有足夠的記憶體來複制 msgp 指向的訊息。
msgrcv() 失敗時,errno 將設定為以下值之一
E2BIG 訊息文字長度大於 msgsz,並且在 msgflg 中未指定 MSG_NOERROR
EACCES 呼叫程序對訊息佇列沒有讀許可權,並且沒有 CAP_IPC_OWNER 功能。
EAGAIN 佇列中沒有可用訊息,並且在 msgflg 中指定了 IPC_NOWAIT
EFAULT msgp 指向的地址無法訪問。
EIDRM 在程序休眠以接收訊息時,訊息佇列已刪除。
EINTR 在程序休眠以接收訊息時,程序捕獲到訊號。
EINVAL msgqid 無效,或 msgsz 小於 0。
ENOMSG msgflg 中指定了 IPC_NOWAIT,並且訊息佇列上不存在請求型別的訊息。

符合標準

SVr4,POSIX.1-2001。

備註

msgp 引數在 libc4、libc5、glibc 2.0、glibc 2.1 中宣告為 struct msgbuf *。根據 SUSv2 和 SUSv3 的要求,它在 glibc 2.2 及更高版本中宣告為 void *

以下訊息佇列資源限制會影響 msgsnd() 呼叫

標籤描述
MSGMAX 訊息文字的最大大小:8192 位元組(在 Linux 上,可以透過 /proc/sys/kernel/msgmax 讀取和修改此限制)。
MSGMNB 訊息佇列的預設最大大小(以位元組為單位):16384 位元組(在 Linux 上,可以透過 /proc/sys/kernel/msgmnb 讀取和修改此限制)。超級使用者可以透過 msgctl() 系統呼叫將訊息佇列的大小增加到超過 MSGMNB
實現對系統範圍內的最大訊息頭數 (MSGTQL) 和系統範圍內的訊息池的最大大小 (MSGPOOL) 沒有內在限制。

參見



previous next Printer Friendly

廣告


  

廣告



廣告