天天看點

Linux IPC實踐(8) --共享記憶體/記憶體映射

    共享記憶體區是最快的IPC形式。一旦這樣的記憶體映射到共享它的程序的位址空間,這些程序間資料傳遞不再涉及到核心,換句話說是程序不再通過執行進入核心的系統調用來傳遞彼此的資料(如圖)。

Linux IPC實踐(8) --共享記憶體/記憶體映射

共享記憶體 VS. 其他IPC形式

     用管道/消息隊列傳遞資料

Linux IPC實踐(8) --共享記憶體/記憶體映射

用共享記憶體傳遞資料

Linux IPC實踐(8) --共享記憶體/記憶體映射

    共享記憶體生成之後,傳遞資料并不需要再走Linux核心,共享記憶體允許兩個或多個程序共享一個給定的存儲區域,資料并不需要在多個程序之間進行複制,是以,共享記憶體的傳輸速度更快!

将檔案/裝置空間映射到共享記憶體區

參數:

    addr:  要映射的起始位址, 通常指定為NULL, 讓核心自動選擇;

    length: 映射到程序位址空間的位元組數;

    prot: 映射區保護方式(見下);

    flags: 标志(見下);

    fd: 檔案描述符;

    offset: 從檔案頭開始的偏移量;

prot

說明

PROT_READ

頁面可讀

PROT_WRITE

頁面可寫

PROC_EXEC

頁面可執行

PROC_NONE

頁面不可通路

flags

MAP_SHARED

變動是共享的

MAP_PRIVATE

變動是私有的

MAP_FIXED

準确解釋addr參數, 如果不指定該參數, 則會以4K大小的記憶體進行對齊

MAP_ANONYMOUS

建立匿名映射區, 不涉及檔案

mmap傳回值:

    成功: 傳回映射到的記憶體區的起始位址;

    失敗: 傳回MAP_FAILED;

記憶體映射示意圖:

Linux IPC實踐(8) --共享記憶體/記憶體映射

(注意: 記憶體映射時, 是以頁面(4K)作為機關)

map注意點:

    1. 記憶體映射不能(也不可能)改變檔案的大小;

    2. 可用于程序間通信的有效位址空間不完全受限于映射檔案的大小, 而應該以記憶體頁面的大小為準(見下面測試);

    3. 檔案一旦被映射之後, 所有對映射區域的通路實際上是對記憶體區域的通路; 映射區域内容寫會檔案時, 所寫内容不能超過檔案的大小.

msync函數

對映射的共享記憶體執行同步操作

    addr: 記憶體起始位址;

    length: 長度

    flags: 選項

MS_ASYNC

執行異步寫

MS_SYNC

執行同步寫, 直到核心将資料真正寫入磁盤之後才傳回

MS_INVALIDATE

使高速緩存的資料失效

傳回值:

    成功: 傳回0;

    失敗: 傳回-1;

繼續閱讀