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 指定。允許長度為零的訊息(即沒有 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

廣告


  

廣告



廣告