天天看點

POSIX 消息隊列 之 概述 連結方式

NAME

mq_overview —— POSIX消息隊列概述

DESCRIPTION

POSIX消息隊列允許程序以消息的形式交換資料。此API與System V消息隊列(msgget(2),msgsnd(2),msgrcv(2)等)有明顯不同,但做的事情差不多。

消息隊列通過mq_open(3)建立和打開,此函數傳回一個消息隊列描述符(mqd_t),它用于之後的調用中引用打開的消息隊列。每個消息隊列由一個名字辨別,該名字具有這樣的格式/somename,亦即,一個空字元結尾,以斜線開頭,最多跟着NAME_MAX(即255)個字元,并且這些字元都不能是斜線。若傳遞相同的名字給mq_open,兩個程序可以操作同一個隊列。

消息通過調用mq_send(3)和mq_receive(3)傳遞。當一個程序結束使用該隊列,則它調用mq_close(3),當一個隊列不再需要了,則可以調用mq_unlink(3)删除。隊列屬性可以調用mq_getattr(3)/mq_setattr(3)擷取/修改。一個程序可以在一個空隊列上調用mq_notify請求消息到達的異步通知。

消息隊列描述符引用到一個打開的消息隊列(類比open(2))。fock(2)之後,子程序繼承父程序隊列描述符的拷貝,兩個描述符都引用到父程序的那個描述符。兩個程序持有的描述符共享與消息隊列描述符相關聯的标記(mq_flags)。

每個消息都有一個關聯的優先級,消息總是從最高優先級交給接收程序。消息優先級範圍從0(低優先級)到sysconf(_SC_MQ_PRIO_MAX)-1(高優先級)。Linux下,sysconf(_SC_MQ_PRIO_MAX)傳回32768,但是POSIX.1-2001隻要求支援0到31的優先級即可,許多實作也隻提供這個範圍。

餘下的部分描述一些POSIX消息隊列在Linux實作上的特殊細節。

庫接口和系統調用

大多數情況下,上面列出的mq_*()庫接口對應到的底層的系統調用是相同的名字。對應的情況羅列于下:

庫接口 系統調用

mq_close(3) close(2)

mq_getattr(3) mq_getsetattr(2)

mq_notify(3) mq_notify(2)

mq_open(3) mq_open(2)

mq_receive(3) mq_timedreceive(2)

mq_send(3) mq_timedsend(2)

mq_setattr(3) mq_getsetattr(2)

mq_timedreceive(3) mq_timedreceive(2)

mq_timedsend(3) mq_timedsend(2)

mq_unlink(3) mq_unlink(2)

版本

POSIX消息隊列在核心2.6.6後支援。

Glibc在版本2.3.4後提供支援。

核心配置

可通過CONFIG_POSIX_MQUEUE核心配置選項支援POSIX消息隊列。此選項預設被啟用。

持久性

POSIX消息隊列具有核心持久性:如果沒有調用mq_unlink移除,消息隊列将在系統關閉之前一直存在。

連結

使用POSIX消息隊列API的程式必須帶選項編譯cc -lrt以連結到實時庫librt。

/proc接口

下列接口可以用于限制核心記憶體在POSIX消息隊列上的消耗量:

/proc/sys/fs/mqueue/msg_max

此檔案可以用于檢視和修改在隊列中排隊消息的數量的上界。此值可以作為一個上限值在傳遞給mq_open的參數attr->mq_msgmax中給定。msg_max的預設值是10,最小值是1(在核心2.6.28之前是10)。此值上限是HARD_MAX:131072/sizeof(void*)(x86下是32768)。特權程序(CAP_SYS_RESOURCE)可以忽略此限制,但是HARD_MAX的上界依然存在。

/proc/sys/fs/mqueue/msgsize_max

此檔案可以用于檢視和修改消息大小最大值的上界。此值可以在attr->mq_msgsize指定并傳遞給mq_open。msgsize_max的預設值是1,048,576(核心2.6.28之前的上限是INT_MAX,x86下為2,147,483,647)。特權程序(CAP_SYS_RESOURCE)可以忽略此限制。

/proc/sys/fs/mqueue/queues_max

此檔案可以用于檢視和修改整個系統上可建立的消息隊列的數量的限制值。一旦到達此限制,則隻有特權程序(CAP_SYS_RESOURCE)才可以建立新的消息隊列。預設值是256,可以被修改為0到INT_MAX之間的任意值。

資源限制

資源限制RLIMIT_MSGQUEUE,限制屬于一個有效使用者ID的所有消息隊列消耗的空間量。參見getrlimit(2)。

挂載消息隊列檔案系統

Linux下,消息隊列被建立在虛拟檔案系統中。(其它實作可能也提供這樣的特性,但細節可能不一樣)此檔案系統可以使用以下指令挂載(由超級使用者):

該目錄的粘連位自動被啟用。

在檔案系統挂載上去之後,系統上的消息隊列就可以像處理檔案那樣用指令檢視和處理了。(如ls, rm)

該目錄的每個檔案内容由單行組成,顯示隊列的有關資訊:

所有的字段如下:

QSIZE   隊列中的所有消息所占位元組數。

NOTIFY_PID

如果此值非0,則表示程序PID為此值的程序調用mq_notify(3)在此隊列上注冊了一個異步消息通知。

餘下的字段描述通知如何發生。

NOTIFY 通知方式:0是SIGEV_SIGNAL,1是SIGEV_NONE,2是SIGEV_THREAD。

SIGNO 用于SIGEV_SIGNAL的信号數值。

輪詢消息隊列描述符

Linux下,消息隊列描述符實際上是一個檔案描述符,可以使用select,poll,epoll監視。但不可移植。

CONFORMING TO

POSIX.1-2001.

NOTES

System V消息隊列(msgget(2), msgsnd(2), msgrcv(2), etc.)是老一些的在程序之間交換消息的API。POSIX消息隊列提供一個設計得更好的接口,但POSIX消息隊列不如System V消息隊列那樣被廣泛支援。

Linux目前(2.6.26)暫不支援對POSIX消息隊列的ACLs。 

EXAMPLE

一個使用各種消息隊列函數的例子在mq_notify(3)中展示。

SEE ALSO

getrlimit(2), mq_getsetattr(2), poll(2), select(2), mq_close(3),

mq_getattr(3), mq_notify(3), mq_open(3), mq_receive(3), mq_send(3),

mq_unlink(3), epoll(7)

COLOPHON

This page is part of release 3.23 of the Linux man-pages project. A

description of the project, and information about reporting bugs, can

繼續閱讀