歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux技術 >> Linux消息隊列

Linux消息隊列

日期:2017/3/3 11:17:47   编辑:Linux技術

什麼是消息隊列

消息隊列可以分為隊列和消息隊列

隊列是從開始到結束,有序的排放消息。消息隊列是用來在應用程序發送消息,隊列中存放了一些待處理的消息。

消息

消息用來在接受者和發送者之間傳輸,它本質上是一個字節數組,上面有一些頭信息。一個消息示例可以是任何告訴一個系統開始處理任務或完成任務的信息。

消息隊列的基本結構是簡單的,有一個客戶端應用程序稱為生產者,創建消息,並將它們傳送到消息隊列。其他應用程序,稱為消費者,連接到隊列,並得到要處理的消息。放置在隊列上的消息被存儲,直到用戶處理它們為止。

消息隊列API

創建新消息隊列或取得已存在消息隊列

[code]#include <sys/msg.h>
------------------------------------
int msgget(key_t key, int msgflg);
參數解釋key鍵值,每個消息對了key值不同,可以使用ftok生成對於的keymsgflgIPC_CREAT: 如果沒有該隊列,則創建該隊列。如果該隊列已經存在,返回該隊列ID.IPC_CREAT & IPC_EXCL: 如果該隊列不存在創建,如果存在返回失敗EEXIST.向隊列讀或者寫數據

[code]#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);
參數解釋msqid消息隊列的描述符IDmsgp執行消息緩沖區的指針,用來存儲消息。格式如下:msgsz消息的大小msgflgIPC_NOWAIT: 如果消息隊列中沒有數據,則立刻返回不用等待。MSG_NOERROR:如果消息隊列長度大於msgsz,截斷消息。
[code] struct msgbuf 
 {
      long mtype;       /* message type, must be > 0 */
      char mtext[1];    /* message data */
 };

設置消息隊列屬性

[code]#include <sys/msg.h>
---------------------
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
參數解釋msgid消息隊列idcmd隊列執行的命令bug執行msqid_ds的指針進一步對cmd名字做詳細解釋

cmd解釋IPC_STAT取得此隊列的msqid_ds結構,存在在buf指向的結構中。IPC_SET該命令用來設置消息隊列的屬性,要設置的屬性存儲在buf中。IPC_RMID從內核中刪除 msqid 標識的消息隊列。

kernel關於IPC參數

名稱含義auto_msgmni根據系統memory增加,移除或者namespace創建,移除自動獲取msgmni的值msgmni該文件指定消息隊列標識的最大數目,即系統范圍內最大多少個消息隊列。msgmnb該文件指定一個消息隊列的最大長度(bytes)。msgmax該文件指定了從一個進程發送到另一個進程的消息的最大長度(bytes)。以上信息可以根據ipcs -l獲得系統的信息
[code]------ Messages: Limits --------
max queues system wide = 2779
max size of message (bytes) = 8192
default max size of queue (bytes) = 16384

根據kernel.txt可以得知,auto_msgmni的值默認是1,當設置為0的時候,就不能自動獲取msgmni

[code]root@test:# cat /proc/sys/kernel/auto_msgmni 
1
root@test:#
而在K4.4版本中。你會發現auto_msgmni居然是0,而且設置1設置失敗。

[code]root@test:/ # cat /proc/sys/kernel/auto_msgmni 
0
root@test:/ # echo 1 > /proc/sys/kernel/auto_msgmni
root@test:/ # cat /proc/sys/kernel/auto_msgmni     
0
root@test:/ #
這到底是什麼原因? 可以通過查看kernel的代碼得知。

[code]kernel/ipc_sysctl.c
------------------------
{
        .procname   = "auto_msgmni",
        .data       = NULL,
        .maxlen     = sizeof(int),
        .mode       = 0644,
        .proc_handler   = proc_ipc_auto_msgmni,
        .extra1     = &zero,
        .extra2     = &one,
},
以上是auto_msgmni的默認配置信息,而proc_ipc_auto_msgmni是設置auto_msgmni的回調函數。

[code] static int proc_ipc_auto_msgmni(struct ctl_table *table, int write,      void __user *buffer, size_t *lenp, loff_t *ppos)
 {
    struct ctl_table ipc_table;
    int dummy = 0;
    memcpy(&ipc_table, table, sizeof(ipc_table));
    ipc_table.data = &dummy;

    if (write)
        pr_info_once("writing to auto_msgmni has no effect");

    return proc_dointvec_minmax(&ipc_table, write, buffer, lenp, ppos);
 }
可以看到一句打印: 設置auto_msgmni已經沒有作用了。

Copyright © Linux教程網 All Rights Reserved