利用共享記憶體實現訊息佇列

2021-06-22 04:59:34 字數 2179 閱讀 7561

日曆登入管理器

2009-02-28 22:02:44

|  分類:

windows

|  標籤:|舉報

|字型大小大中

小訂閱

在windows中沒有方便操作message queue(訊息佇列)的api(在vxworks中有msgqcreate,msgqsend,msgqreceive等操作訊息佇列的 api),訊息佇列和油槽、管道技術類似,為程序間的通訊提供方便高效的機制。現簡單介紹訊息佇列的機制:乙個訊息佇列由一定數量的有著固定大小訊息緩衝區組成,乙個程序可以傳送訊息到訊息佇列裡,也可以接收訊息佇列裡的訊息。為了在windows下方便實現這樣的訊息佇列,這裡要利用到共享記憶體機制。

共享記憶體的原理將一段(虛擬)記憶體分別對映到每個程序的位址空間裡,然後每個程序都可以對自己的這段空間進行讀寫操作,這就相當於對同乙個記憶體進行讀寫,達到了共享的目的。

該函式為乙個檔案建立乙個未名或具名的檔案映像,其中當hfile為invalid_handle_value時,系統將為paging file建立檔案映像;lpname指定檔案映像的名字,當該引數為null時,系統將建立乙個「私有」的檔案映像,別的程序將無法通過名字開啟該檔案映像,所以該引數需要指定乙個全域性統一的名字(一般可以通過guid命名)。

簡單介紹了這2個api,接下來將介紹訊息佇列的實現。

1:既然共享記憶體可以由每個程序非同步的讀和寫,所以需要建立乙個鎖,用於保護共享記憶體。這裡使用mutex來實現。

當訊息佇列send/receive時,需要先獲取該mutex,當獲取成功後,才可以對共享記憶體進行寫操作。簡單的偽碼實現如下:

if(waitforsingleobject(m_hresmutex, infinite) == wait_object_0)

2:當send訊息時,如果訊息佇列滿,怎麼辦?當然要等了,但要等多少才知道有空餘的訊息buffer呢?所以必須提供乙個事件機制,告訴在等的send操作;當receive訊息時,如果訊息佇列空,怎麼辦?當然也要等了,但要等多久才知道訊息佇列有訊息呢?所以也得提供乙個事件機制,告訴在等的receive操作。這裡使用event裡模擬,分別定義如下的兩個event:

handle  m_hsendevent, m_hreceiveevent;

3:雖然對共享記憶體進行了讀寫保護,但是卻不知道往訊息佇列的什麼地方讀寫,怎麼辦?當然得提供乙個結構來儲存訊息佇列的基本資訊了,比如訊息大小,訊息數量等,所以定義如下結構:

//訊息佇列頭資訊結構

typedef struct _msgq_header

msgq_header, *pmsgq_header;

其中魔數用於判斷該共享記憶體是否為訊息佇列;readindex 和 writeindex 為讀寫的佇列索引;該結構存放於共享記憶體的頭部。

[本訊息佇列採用環形佇列來模擬的]

4:根據以上條件定義如下的cmsgq類:

class cmsgq 

;下面簡單說明幾個重要函式的實現:

a:create

bool cmsgq::create(lpctstr name, int msgsize, int msgcnt)

return true;

}b:send

bool cmsgq::send(lpvoid buf, dword datasize, dword waittime)

//判斷佇列是否滿,如果滿,則對待m_hsendevent waittime毫秒,**略。

if(waitforsingleobject(m_hresmutex, waittime) == wait_object_0)

releasemutex(m_hresmutex);

}return bret;

}c:receive

bool cmsgq::receive(lpvoid buf, dword bufsize, dword waittime)

//判斷佇列是否為空,若為空,則等待m_hreceiveevent waittime毫秒,**略。

if(waitforsingleobject(m_hresmutex, waittime) == wait_object_0)

releasemutex(m_hresmutex);

}return bret;

訊息佇列的簡單實現已經全部介紹完了。

管道 訊息佇列 共享記憶體

管道通訊 pipe 管道通訊方式的中間介質是檔案,通常稱這種檔案為管道檔案。兩個程序利用管道檔案進行通訊時,乙個程序為寫程序,另乙個程序為讀程序。寫程序通過寫端 傳送端 往管道檔案中寫入資訊 讀程序通過讀端 接收端 從管道檔案中讀取資訊。兩個程序協調不斷地進行寫 讀,便會構成雙方通過管道傳遞資訊的流...

Linux 記憶體共享與訊息佇列

共享記憶體 共享共存區域是被多個程序共享的一部分物理記憶體。如果多個程序都 把該記憶體區域對映到自己的虛擬位址空間,則這些程序就都可以直接 訪問該共享記憶體區域,從而可以通過該區域進行通訊。共享記憶體是進 程間共享資料的一種最快的方法,乙個程序向共享記憶體區域寫入了數 據,共享這個記憶體區域的所有程...

linux 訊息佇列 和 共享記憶體

1.基本知識 存在於核心中2.基本流程及函式 傳送 接收 1 申請key值 2 建立 開啟 訊息佇列 3 傳送訊息 建立結構體 typedef struct msg t 1 key t key ftok 5 if key 0 2 int msgid msgget key,ipc creat 0777...