2011-03-12 24 views

回答

5

Adrian的回答是正確的,但是因爲這是Linux上遇到的一個令人沮喪的常見錯誤,當第一次嘗試將POSIX消息隊列用於任何非平凡的事情時,我想我會添加一些有用的細節。

首先,要了解的RLIMIT_MSGQUEUE資源限制,參見下式的man setrlimit

RLIMIT_MSGQUEUE(由於Linux 2.6.8) 指定在可對POSIX消息隊列被分配的字節數的限制用於調用進程的真實用戶標識。這個限制是爲mq_open(3)強制執行的。用戶根據下式針對該限制產生計數(直到它被移除),每個消息隊列:

bytes = attr.mq_maxmsg * sizeof(struct msg_msg *) + 
     attr.mq_maxmsg * attr.mq_msgsize 

其中attr是指定爲第四個參數mq_open(3)的mq_attr結構。 公式中的第一個加數(包含sizeof(struct msg_msg *)(Linux/i386上的4個字節))確保用戶不能創建無限數量的零長度消息(但這些消息每個消耗一些用於簿記的系統內存高架)。

鑑於Linux上的默認MQ設置(mq_maxmsg = 10,mq_msgsize = 8192),上述式工程以僅約10的819200個字節的缺省限制消息隊列。因此,爲什麼你會盡快遇到這個問題。忘記關閉和取消一連串的隊列後,與他們一起完成。

爲了提高RLIMIT_MSGQUEUE資源限制,以允許用戶上限,您可以使用類似的應用程序的啓動代碼如下:

#ifdef __linux__ 
    // Attempt to raise the resource limits for POSIX message queues to 
    // the current hard limit enforced for the current real user ID: 
    struct rlimit rlim = {RLIM_INFINITY, RLIM_INFINITY}; 
    const int rc = getrlimit(RLIMIT_MSGQUEUE, &rlim); 
    if (rc == 0 && rlim.rlim_cur != rlim.rlim_max) { 
     rlim.rlim_cur = rlim.rlim_max; 
     setrlimit(RLIMIT_MSGQUEUE, &rlim); 
    } 
#endif 

如果您還確保您設置的mq_maxmsgmq_msgsize屬性在打開隊列時要降低值(請參閱man mq_open),即使在硬限制的默認限制範圍內,您也可以獲得幾百個隊列。當然,取決於您的特定用例。

如果您具有對系統的root訪問權限,則調整RLIMIT_MSGQUEUE硬性限制並不困難。一旦確定了極限應該是什麼,請調整/etc/security/limits.conf中的系統範圍設置。例如,設置的4兆字節爲www-data用戶組一硬一軟的限制,併爲超級用戶沒有限制,你下面的行添加到文件:

@www-data - msgqueue 4194304 
root  - msgqueue unlimited 
+0

另一個陷阱:小心計算需要的字節不僅對於一個隊列,而且對於所有隊列,如果使用多個隊列,則不限於此。 – Alex 2014-09-10 15:16:17

5

最可能的原因是您要求的消息隊列大於允許的空間。系統限制在/proc/sys/fs/mqueue/中進行控制。每個用戶的限制(RLIMIT_MSGQUEUE)也控制着單個用戶可以分配的總字節數。要檢查系統上的設置,請查看ulimit -q的值,該值默認爲819200字節。

開發人員認爲消息隊列適用於小型低延遲消息。分發使用較大消息隊列的應用程序很困難,因爲需要系統管理員更改以提高限制。

相關問題