Linux程序間通訊原始碼剖析,共享記憶體 mmap

2021-05-23 22:24:50 字數 2395 閱讀 1975

來自:http://blog.csdn.net/dancing999/archive/2008/01/13/2042473.aspx

範例1:兩個程序通過對映普通檔案實現共享記憶體通訊

範例1包含兩個子程式:map_normalfile1.c及map_normalfile2.c。編譯兩個程式,可執行檔案分別為map_normalfile1及map_normalfile2。兩個程式通過命令列引數指定同乙個檔案來實現共享記憶體方式的程序間通訊。map_normalfile2試圖開啟命令列引數指定的乙個普通檔案,把該檔案對映到程序的位址空間,並對對映後的位址空間進行寫操作。map_normalfile1把命令列引數指定的檔案對映到程序位址空間,然後對對映後的位址空間執行讀操作。這樣,兩個程序通過命令列引數指定同乙個檔案來實現共享記憶體方式的程序間通訊。

下面是兩個程式**:

map_normalfile1.c首先定義了乙個people資料結構,(在這裡採用資料結構的方式是因為,共享記憶體區的資料往往是有固定格式的,這由通訊的各個程序決定,採用結構的方式有普遍代表性)。map_normfile1首先開啟或建立乙個檔案,並把檔案的長度設定為5個people結構大小。然後從mmap()的返回位址開始,設定了10個people結構。然後,程序睡眠10秒鐘,等待其他程序對映同乙個檔案,最後解除對映。

map_normfile2.c只是簡單的對映乙個檔案,並以people資料結構的格式從mmap()返回的位址處讀取10個people結構,並輸出讀取的值,然後解除對映。

分別把兩個程式編譯成可執行檔案map_normalfile1和map_normalfile2後,在乙個終端上先執行./map_normalfile2 /tmp/test_shm,程式輸出結果如下:

initialize over

umap ok

在map_normalfile1輸出initialize over 之後,輸出umap ok之前,在另乙個終端上執行map_normalfile2 /tmp/test_shm,將會產生如下輸出(為了節省空間,輸出結果為稍作整理後的結果):

name: b age 20; name: c age 21; name: d age 22; name: e age 23; name: f age 24;

name: g age 25; name: h age 26; name: i age 27; name: j age 28; name: k age 29;

在map_normalfile1 輸出umap ok後,執行map_normalfile2則輸出如下結果:

name: b age 20; name: c age 21; name: d age 22; name: e age 23; name: f age 24;

name: age 0; name: age 0; name: age 0; name: age 0; name: age 0;

從程式的執行結果中可以得出的結論

1、 最終被對映檔案的內容的長度不會超過檔案本身的初始大小,即對映不能改變檔案的大小;

2、 可以用於程序通訊的有效位址空間大小大體上受限於被對映檔案的大小,但不完全受限於檔案大小。開啟檔案被截短為5個people結構大小,而在map_normalfile1中初始化了10個people資料結構,在恰當時候(map_normalfile1輸出initialize over 之後,輸出umap ok之前)呼叫map_normalfile2會發現map_normalfile2將輸出全部10個people結構的值,後面將給出詳細討論。 注:在linux中,記憶體的保護是以頁為基本單位的,即使被對映檔案只有乙個位元組大小,核心也會為對映分配乙個頁面大小的記憶體。當被對映檔案小於乙個頁面大小時,程序可以對從mmap()返回位址開始的乙個頁面大小進行訪問,而不會出錯;但是,如果對乙個頁面以外的位址空間進行訪問,則導致錯誤發生,後面將進一步描述。因此,可用於程序間通訊的有效位址空間大小不會超過檔案大小及乙個頁面大小的和。

3、 檔案一旦被對映後,呼叫mmap()的程序對返回位址的訪問是對某一記憶體區域的訪問,暫時脫離了磁碟上檔案的影響。所有對mmap()返回位址空間的操作只在記憶體中有意義,只有在呼叫了munmap()後或者msync()時,才把記憶體中的相應內容寫回磁碟檔案,所寫內容仍然不能超過檔案的大小。

範例2:父子程序通過匿名對映實現共享記憶體

考察程式的輸出結果,體會父子程序匿名共享記憶體:

child read: the 1 people's age is 20

child read: the 2 people's age is 21

child read: the 3 people's age is 22

child read: the 4 people's age is 23

child read: the 5 people's age is 24

parent read: the first people,s age is 100

umap

umap ok

ucos II 任務間通訊原始碼分析

ucos ii 2.0版本的任務間通訊提供訊息郵箱和訊息佇列兩種機制,都基於核心的事件控制塊機制實現。訊息郵箱 訊息郵箱主要函式分析 訊息佇列 訊息佇列全域性變數 typedef struct os q os q typedef struct os q data os ext os q osqfre...

linux socket通訊原始碼

初學socket通訊,參考的是linuxc程式設計大全的23章的23 5例子,但是發現這個例子原始碼裡有好幾處錯誤,因為初學,很多不懂,吃了虧,因此將修改後能正常執行的 記錄在這裡 參考 server.c include include include include include include...

Handler通訊 原始碼分析

1.messagequeue 訊息佇列 執行緒中更新 ui 的時候經常是呼叫 sendmessage 和 sendmessagedelayed 這樣 我跟蹤 進入到 handler 的 sendmessage 方法 public final boolean sendmessage message m...