NAME
mq_open - 打開一個消息隊列 (REALTIME)
SYNOPSIS
#include <mqueue.h>
mqd_t mq_open(const char *name, int oflag, ...)
mqd_t mq_open(const char *name, int oflag, mode_t mode, mq_attr* attr) //O_CREAT
DESCRIPTION
mq_open() 函數會通過一個消息隊列描述符(類型是mqd_t)建立一個進程與一個消息隊列的連接.
該函數會創建一個打開的消息隊列的描述符, 其他函數就可以通過這個描述符操作消息隊列.
PARAMETERS
①name
參數 name 是一個指向消息隊列名稱的指針. 但是名字是否出現在文件系統中,是否對其他以路徑名為參數的函數可見是未定義的.
參數 name 的長度限制是由系統實現決定的(如何獲取這個限制),不需要遵守路徑名的限制 {PATH_MAX} 和 {NAME_MAX}.
如果 name 參數以"/"字符開頭, 只有name沒有被刪除,所有使用相同name值調用mq_open函數的線程,訪問的都是同一個消息隊列,
如果 name 參數不是以"/"字符開頭,效果是由系統實現決定的.所以name參數一定要以"/"字符開頭.
②oflag
參數 oflag 表示想要訪問(receive/send)消息隊列的方式.
參數 oflag 是由下列宏組合計算出來的, 注意必須包含前3個(訪問模式) 中的一個:
O_RDONLY (只讀)
打開一個消息隊列用來接受消息.
調用進程可以使用mq_open返回的描述符用於函數 mq_receive(), 但是不能用於函數 mq_send().
一個消息隊列可以在相同或不同的進程中多次打開用來接收消息.
O_WRONLY (只寫)
打開一個消息隊列用來發送消息.
調用進程可以使用mq_open返回的描述符用於函數 mq_send(), 但是不能用於函數 mq_receive().
一個消息隊列可以在相同或不同的進程中多次打開用來發送消息.
O_RDWR (讀寫)
打開一個消息隊列用即可用來發送消息也可以用來接受消息.
調用進程可以使用任何支持O_RDONLY 和O_WRONLY 訪問模式的函數.
一個消息隊列可以在相同或不同的進程中多次打開用來發送消息.
Any combination of the remaining flags may be specified in the value of oflag:
O_CREAT (創建)
- 創建一個消息隊列. 使用這個參數需要追加2個參數: ③ mode(類型是mode_t ), 和 ④attr(類型是mq_attr*).
- 如果name參數指定的消息隊列已經存在, 那么這個參數將不起任何作用, 除非像下面 O_EXCL 中提到的情況;
- 否則, 會創建一個空的消息隊列. 消息隊列的用戶ID會被設置成這個進程的實際的用戶ID.
- 消息隊列的組ID會被設置成這個進程的實際的組ID; 然而, 如果參數 name 指向的消息隊列在文件系統中可見, 那么組ID會被設置成包含消息隊列的目錄的組ID.
- 如果參數mode中的位與文件權限中位不同,這種情況是未定義的.
- 如果 attr 是 NULL, 創建的消息隊列是系統實現的默認屬性. 如果 attr 不是 NULL 並且調用進程對參數name指定的文件有特定的權限 (什么權限),
- 那么消息隊列的屬性 mq_maxmsg 和 mq_msgsize 會被設置成 attr 中的屬性. 屬性 mq_flags 和 mq_curmsgs 會被忽略.
- 如果 attr 不是 NULL , 並且調用進程對參數name指定的文件沒有特定的權限,函數 mq_open() 會返回失敗,不會創建消息隊列.
O_EXCL (既存檢查)
- 如果 O_EXCL 和O_CREAT同時被設置了, 如果消息隊列應經存在,那么函數 mq_open() 會返回失敗.
- 提供了檢查消息隊列是否存在的方法, 如果設置了 O_EXCL 必須同時設置 O_CREAT 否則結果未定義.
O_NONBLOCK (非阻塞)
- 決定函數 mq_send() 和 mq_receive() 在獲取當前無法獲得的資源或消息時,是一直等待(阻塞), 還是返回失敗並將 errno 設置成 [EAGAIN];
RETURN VALUE
如果函數執行成功, 函數返回一個描述符
如果函數執行失敗,函數返回 (mqd_t)-1 並且設置errno,errno的種別詳見下面的ERRORS一節.
ERRORS
[EACCES]
The message queue exists and the permissions specified by oflag are denied, or the message queue does not exist and permission to create the message queue is denied.
[EEXIST]
O_CREAT and O_EXCL are set and the named message queue already exists.
[EINTR]
函數 mq_open() 被信號中斷.
[EINVAL]
函數 mq_open() 不支持參數name指定的路徑.
[EINVAL]
設置了O_CREAT標志, 參數3 attr 不是NULL;並且 mq_maxmsg 或 mq_msgsize 小於等於0.
[EMFILE]
本進程中使用了過多的消息隊列描述符 或 文件描述符.
[ENFILE]
系統中打開的消息隊列數目超過了系統支持的最大數.
[ENOENT]
沒有設置O_CREAT標志,並且指定的消息隊列不存在.
[ENOSPC]
空間不足,無法創建新的消息隊列.
[ENAMETOOLONG]
參數 name 的長度超過系統定義的最大長度.
在不支持XSI系統中,name 的長度超過了 {_POSIX_PATH_MAX},在支持XSI系統中,name 的長度超過了 {_XOPEN_PATH_MAX};或者
在不支持XSI系統中,某一級路徑的長度超過了 {_POSIX_NAME_MAX},在支持XSI系統中,某一級路徑的長度超過了 {_XOPEN_NAME_MAX};
EXAMPLES