Linux 訊息佇列

2021-10-23 10:33:23 字數 3940 閱讀 3026

1、定義

訊息佇列是訊息的鍊錶,存放在核心中並由訊息佇列識別符號表示。訊息佇列提供了一種從乙個程序向另乙個程序傳送乙個資料塊的方法,這個資料塊由訊息型別和資料等資訊組成。訊息佇列遵循先進先出的策略,但因為存在訊息型別,有優先順序,故訊息佇列類似於乙個優先順序佇列

核心為每個訊息佇列維護了乙個資料結構msqid_ds,用於標識訊息佇列,成員有:

struct msqid_ds;
通過msg_perm標識乙個訊息佇列,通過msqid_ds表示乙個訊息佇列,根據msg_first,msg_last成員維護乙個先進先出的msg鍊錶佇列(固定型別)。每次傳送訊息時,將其構造成msg結構物件,即自己定義的訊息結構體,裡面可以包含訊息型別、內容等資訊,並新增到msqid_ds成員維護的鍊錶佇列中,如下圖所示:

訊息佇列和管道類似,在訊息長度和數目上都有一定的限制,具體的系統限制如下表所示:

2、特點

利用訊息佇列進行程序間銅通訊的方式,我們可以模擬為:a需要傳送資訊給b,但是因為距離原因不能當前給b,那麼就需要a先把資訊給xx位址的ss驛站,驛站將其儲存,儲存箱編號是yyyy,b要去除這個資訊,必須要到xx位址的ss驛站取出編號為yyyy的箱子,開啟才可以獲取。

在訊息佇列中,鍵(key)值就相當於xx位址,訊息佇列識別符號相當於ss驛站,訊息型別相當於yyyy編號的箱子。

同一鍵(key)值可以保證是同乙個訊息佇列,同乙個訊息佇列識別符號才能保證不同程序可以相互通訊,同一訊息型別才能保證某個程序取出的是對方的資訊。

1、鍵值

system v提供的程序間通訊機制需要乙個key值,通過key值就可以在系統內獲得乙個唯一的訊息佇列識別符號,key值可以是人為指定的數字,強轉為key_t型別即可,也可以通過ftok函式獲得。

(key_t)1234;//1234就為key值,在建立獲取訊息佇列函式的第乙個引數可以這樣寫
# include# includekey_t ftok(const char* pathname,int proj_id);

成功返回key值,失敗返回-1

引數為:路徑名;專案id,非0整數,只有低8位有效。

2、建立或者獲取乙個訊息佇列

該函式的功能是開啟乙個現存佇列或者建立乙個新佇列,如果多個程序想通過同乙個訊息佇列完成資料通訊,則每個程序使用key值建立或者獲取同乙個訊息佇列的核心物件id。key就類似乙個識別符號,函式原型如下:

int msgget((key_t) key,int flag);
引數:

key為使用者標識如果該值為0,系統會為程序建立乙個程序自用的訊息佇列,否則建立或者開啟乙個新佇列

flag是操作標識,ipc_creat表示不存在就去建立,存在就去獲取即可

返回值:成功返回核心物件的id值,失敗返回-1。

如果多個程序想通過同乙個訊息佇列完成資料通訊,則每個程序使用相同的key值建立或者獲取同乙個訊息佇列的核心物件id值。

3.設定乙個訊息佇列

int msgctl(int msgid,int cmd,struct msqid_ds* buf)
cmd是一些命令,其中pc_rmid(用於刪除訊息佇列)、ipc_get、ipc_set(獲取和設定屬性值)

4、增加資料msgsnd函式

將新訊息新增到訊息佇列中,函式原型為:

# include

intmsgsnd

(int msqid,

struct msgbuf * msgp,

int msgsz,

int msg***)

;

函式返回成功後,與訊息佇列對應的msqid_ds結構得到更新,表明呼叫的程序id,呼叫的時間及佇列中新增的訊息。

msqid為已開啟的訊息佇列id,也就是msgget的返回值

msgp是乙個void型別的指標,該指標指向存放訊息的結構如下

struct msgbuf

msgsz 指定上述訊息結構中有效資料的長度

msg***一般設定為0,也可以設定成ipc_nowait非阻塞的方式

5、接收乙個訊息佇列

int msgrcv(int msqid, struct msgbuf * msgp, int msgsz, long msgtyp, int msg***);
msgtyp表示指定接收的訊息佇列,型別可以為0,表示去接收訊息佇列裡面的第一條訊息。

成功返回mtext中接收的資料長度,失敗返回-1.

我們畫出存在訊息型別時的訊息佇列圖:

可以看到有兩個訊息型別1,2;2的優先順序》1的優先順序,那麼此時的隊列為優先順序佇列。msgrcv一次只能獲取一條訊息,資料之間存在間隔,故不會出現粘連資料的現象。

如果我們要取2型別的資料,因為2的優先順序》1,所以無論前面有多少個1,都無所謂,都可以取出2,但是如果c取1型別的資料,那麼會先取到a程序指向的資料,因為是一種先進先出的結構,所以會先拿到最開始的1。

實現利用訊息佇列實現連個程序間的通訊,a程序給b程序傳送指定訊息「hello",b程序接收後將其列印,定義結構中的:訊息型別為100,位元組大小為128;

將儲存訊息的結構體在msg.h

#include

#include

#include

#include

#include

#include

#pragma once

typedef

struct msgdata

msgdata;

msga.c

#include

"msg.h"

intmain()

msgb.c

#include

"msg.h"

intmain()

測試:

訊息佇列的建立和刪除

可以執行的命令如下:

ipcs -q  //顯示訊息佇列型別

ipcrm -q mspid(訊息佇列的id) //刪除訊息佇列型別

如果a建立訊息佇列,傳送資訊後,再利用ipsc -q msqid刪除訊息佇列,此時再執行b,b會阻塞,因為沒有訊息,但是b會建立出乙個新的訊息佇列,只不過訊息佇列中沒有資訊。如下圖所示:

linux訊息佇列 Linux訊息佇列

訊息佇列,unix的通訊機制之一,可以理解為是乙個存放訊息 資料 容器。將訊息寫入訊息佇列,然後再從訊息佇列中取訊息,一般來說是先進先出的順序。可以解決兩個程序的讀寫速度不同 處理資料速度不同 系統耦合等問題,而且訊息佇列裡的訊息哪怕程序崩潰了也不會消失。最簡單的訊息記憶體的使用流程 ftok函式生...

linux訊息佇列

訊息佇列是核心位址空間中的內部鍊錶,每個訊息佇列都在系統範圍內對應唯一的鍵值,所以,要獲得乙個訊息佇列的描述字,只需提供該訊息佇列的鍵值即可。1 訊息緩衝區結構 存放訊息資料的模板,可在基本定義的基礎上自己定義 在include linux msg.h中宣告,描述如下 struct 可以定義自己的例...

linux 訊息佇列

一 訊息佇列的基本概念 訊息佇列 也叫做報文佇列 是unix系統v版本中3種程序間通訊機制之一。另外兩種是訊號燈和共享記憶體。這些ipc機制使用共同的授權方法。只有通過系統呼叫將標誌符傳遞給核心之後,程序才能訪問這些資源。這種系統ipc物件使用的控制方法和檔案系統非常類似。使用物件的引用標誌符作為資...