msgop() - Unix, Linux系統呼叫
廣告
名稱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 標誌的設定如何,msgsnd 和 msgrcv 永遠不會在被訊號處理程式中斷後自動重啟。) 成功完成時,訊息佇列資料結構將更新如下:
標籤 | 描述 |
|
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) 沒有固有的限制。參見
廣告
|