POSIX訊息佇列

2021-08-15 21:11:15 字數 4896 閱讀 5911

​ 訊息佇列可以認為是乙個鍊錶。程序(執行緒)可以往裡寫訊息,也可以從裡面取出訊息。乙個程序可以往某個訊息佇列裡寫訊息,然後終止,另乙個程序隨時可以從訊息佇列裡取走這些訊息。這裡也說明了,訊息佇列具有隨核心的持續性,也就是系統不重啟,訊息佇列永久存在。

3.2.1 建立(並開啟)、關閉、刪除乙個訊息佇列

#include 

/* for o_* constants */

#include

/* for mode constants */

#include

​mqd_t

mq_open(const

char

*name, int

oflag);

mqd_t

mq_open(const

char

*name, int

oflag, mode_t

mode,

struct

mq_attr

*attr);

​/*  

函式說明:函式建立或開啟乙個訊息佇列,建立後,在/dev/mqueque下可以看到對應檔案

返回值:成功返回訊息佇列描述符,失敗返回-1,錯誤原因存於errno中

name: 檔案路徑,必須以/開頭,而且有且只有乙個/

oflag: 與open的開啟標誌一樣,加上o_creat標誌,能夠建立訊息佇列

mode: 與open的開啟mode一樣

attr: 建立訊息佇列的時候需要,指定訊息佇列大小訊息個數等,為null表示使用預設引數

*//*訊息佇列屬性結構體*/

struct

mq_attr ;

​mqd_t

mq_close(mqd_t

mqdes);

/*  

函式說明:關閉乙個開啟的訊息佇列,表示本程序不再對該訊息佇列讀寫  

返回值:成功返回0,失敗返回-1,錯誤原因存於errno中  */​

intmq_unlink(const

char

*name);

/*  

函式說明:刪除乙個訊息佇列,好比刪除乙個檔案,其他程序再也無法訪問  

返回值:成功返回0,失敗返回-1,錯誤原因存於errno中  

*/

需要注意:

​ 訊息佇列的名字最好使用「/」打頭,並且只有乙個「/」的名字。否則可能出現移植性問題;

它必須符合已有的路徑名規則(最多由path_max個位元組構成,包括結尾的空位元組)。

3.2.2 posix訊息佇列讀寫

訊息佇列的讀寫主要使用下面兩個函式:

#include ​​

intmq_send(mqd_t

mqdes, const

char

*msg_ptr, size_t

msg_len, unsigned

msg_prio);

/*功能:傳送一條訊息到佇列

mqdes:訊息佇列檔案描述符

msg_ptr: 訊息內容

msg_len: 內容長度

msg_prio: 訊息優先順序,它是乙個小於mq_prio_max的數, 數值越大,優先順序越高

返回:若成功則為訊息中位元組數,若出錯則為-1 */​

​ssize_t

mq_receive(mqd_t

mqdes, char

*msg_ptr, size_t

msg_len, unsigned

*msg_prio);  

/*功能:從佇列接收一條訊息

mqdes:訊息佇列檔案描述符

msg_ptr: 訊息內容

msg_len: 內容長度

msg_prio: 訊息優先順序

返回:若成功則為0, 若出錯則為-1

*/

原始碼sendmq.c

#include 

#include

#include

#include

#include

#include

#include

#include

#include

void

error_print(const

char*

msg)

​/*向訊息佇列傳送訊息,訊息佇列名及傳送的資訊通過引數傳遞*/

intmain(int

argc, char

*argv)  

編譯:

gcc

-o sendmq sendmq.c -lrt

執行後可以在/dev/mqueue下看到mymq檔案。

原始碼recvmq.c

#include 

#include

#include

#include

#include

#include

#include

#include

void

error_print(const

char*

msg)

/*讀取某訊息佇列,訊息佇列名通過引數傳遞*/

intmain(int

argc, char

*argv)  

編譯並執行:

gcc

-o recvmq recvmq.c -lrt

需要注意的是:當訊息不斷傳送,達到訊息佇列容量最大值的時候,mq_send將阻塞,知道訊息佇列被接收走,如果訊息還未接收,就把訊息佇列檔案刪除,則訊息丟失。

3.2.3 訊息佇列的屬性

posix訊息佇列的屬性使用如下結構存放:

struct

mq_attr

; /*

佇列可以在建立時由mq_open()函式的第四個引數指定mq_maxmsg,mq_msgsize。 如建立時沒有指定則使用預設值,一旦建立,則不可再改變。

佇列可以在建立後由mq_setattr()函式設定mq_flags */​

#include

​/*取得訊息佇列屬性,放到mqstat中*/

intmq_getattr(mqd_t

mqdes, struct

mq_attr

*mqstat);  

​/*設定訊息佇列屬性,設定值由mqstat提供,原先值寫入omqstat中,只是用來改變o_nonblock標誌*/

intmq_setattr(mqd_t

mqdes, const

struct

mq_attr

*mqstat, struct

mq_attr

*omqstat);  

​均返回:若成功則為0,若出錯為-1

獲取訊息佇列的屬性:

attrmq.c

#include 

#include

#include

#include

#include

#include

#include

#include

void

error_print(const

char*

msg)

intmain()  

編譯並執行:

gcc

-o attrmq attrmq.c -lrt

設定訊息佇列的屬性:

原始碼setarrtmq.c

#include 

#include

#include

#include

#include

#include

#include

#include

void

error_print(const

char*

msg)

intmain()  

mqattr.mq_flags

=o_nonblock;  

mq_setattr(mqd, &

mqattr, null);// mq_setattr()只關注mq_flags  

/*取得訊息佇列屬性*/

ret=

mq_getattr(mqd, &

mqattr);  

if(ret

<

0)  

error_print("mq_getattr");  

printf("nonblock flag:%ld\n", mqattr.mq_flags);  

printf("max msgs:%ld\n", mqattr.mq_maxmsg);  

printf("max msg size:%ld\n", mqattr.mq_msgsize);  

printf("current msg count:%ld\n", mqattr.mq_curmsgs);  

ret=

mq_close(mqd);

if(ret

<

0)error_print("mq_close");

return

0;  

}

編譯執行:

gcc

-o setattrmq setattrmq.c -lrt

訊息佇列系統限制檢視:

cat /proc/sys/fs/mqueue/msg_max #檢視訊息佇列的訊息最大長度

cat /proc/sys/fs/mqueue/msgsize_max #檢視訊息佇列的訊息最大個數

POSIX訊息佇列

訊息佇列可認為是乙個訊息鍊錶,有寫許可權的執行緒可以往訊息佇列中寫訊息,有讀許可權的執行緒可以從佇列中讀取訊息,從而實現資料共享。每個訊息都是一條記錄,具有以下屬性 優先順序 無符號整數或長整數型別 訊息的資料部分長度 資料本身。1 相關函式 標頭檔案 include 建立和開啟 mqd t mq ...

Posix訊息佇列

posix訊息佇列與system v訊息佇列的主要差別 1 對posix訊息佇列的讀總是返回最高優先順序的最早訊息,對system v訊息佇列的讀則可以返回任意指定優先順序的訊息 2 當往乙個空佇列放置乙個訊息時,posix訊息佇列允許產生乙個訊號或啟動乙個執行緒,system v訊息佇列則不提供類...

posix 訊息佇列

posix 訊息佇列 訊息佇列的使用 1.建立訊息佇列mq open const char name,int oflag,mode t mode,struct mq attr attr name 訊息佇列的名稱,以 開頭 oflag 標誌,o rdonly 唯讀 o wronly 只寫 o rdwr...