1. 程式人生 > >Linux程序間通訊(七)---共享記憶體之shmget()、shmat()、shmdt()及其基礎實驗

Linux程序間通訊(七)---共享記憶體之shmget()、shmat()、shmdt()及其基礎實驗

概述

  可以說,共享記憶體是一種最為高效的程序間通訊方式,因為程序可以直接讀寫記憶體,不需要任何資料的複製。為了在多個程序間交換資訊,核心專門留出了一塊記憶體區,這段記憶體區可以由需要訪問的程序將其對映到自己的私有地址空間。因此,程序就可以直接讀寫這一段記憶體區而不需要進行資料的複製,從而大大提高了效率。當然,由於多個程序共享一段記憶體,因此也需要依靠某種同步機制,如互斥鎖和訊號量等。共享記憶體的原理圖如下圖1所示

共享記憶體使用步驟

  ①  建立共享記憶體。也就是從記憶體中獲得一段共享記憶體區域,這裡用到的函式是shmget();

  ②  對映共享記憶體。也就是把這段建立的共享記憶體對映到具體的程序空間中,這裡使用的函式是shmat()。到這一步就可以使用這段共享記憶體了,也就是可以使用不帶緩衝的I/O讀寫命令對其進行操作。

  ③  撤銷對映。使用完共享記憶體就需要撤銷,用到的函式是shmdt()。

函式說明

 

 

基礎實驗1

 功能

   本實驗意在說明如何使用基本的共享記憶體函式。首先建立一個共享記憶體區(採用的共享記憶體的鍵值是IPC_PRIVATE,是因為本實驗中建立的共享記憶體是父子程序間的共用部分),然後建立子程序,在父子兩個程序中將共享記憶體分別對映到各自的程序地址空間中。

    父程序先等待使用者輸入,然後將使用者輸入的字串寫入到共享記憶體,之後向共享記憶體的頭部寫入“WROTE”字串表示父程序已成功寫入資料。子程序一直等到共享記憶體的頭部字串為“WROTE”,然後將共享記憶體的有效資料(在父程序中使用者輸入的字串)在螢幕上列印。父子兩個程序在完成以上工作後,分別解除與共享記憶體的對映關係。

    最後在子程序中刪除共享記憶體。因為共享記憶體自身並不提供同步機制,所以應額外實現不同程序間的同步(如訊號量)。為了簡單起見,在本實驗中用標誌字串來實現非常簡單的父子程序間的同步。

    在本實驗中,用到了一個命令是 ipcs ,它用於報告程序間通訊機制狀態,它可以檢視共享記憶體、訊息佇列等各種程序間通訊機制的情況,這裡使用了system()函式呼叫shell命令"ipcs -m",有關於ipcs命令和system()函式不瞭解的可以查查哈。

源程式

   程式上傳到網站,如有需要,請自行下載,shmem.c檔案點此下載

  




 執行結果

  


基礎實驗2

功能

   完成的功能和基礎實驗1一樣,唯一不同的就是實現同步的方法不一樣,實驗1是利用標誌字元位來實現同步的,而本實驗是利用訊號量實現同步的,如果訊號量不會的話,請看部落格:

源程式

   本程式中有關訊號量的程式碼我是直接複製上一節的程式碼,本實驗的完整程式我上傳到網站,如有需要請自行下載,shmem_sem.c檔案點此下載

   




執行結果

  



希望和實驗1比較,從而對訊號量實現同步有跟深刻的認識。

/*****************************************************************/

如需轉載請註明出處

/****************************************************************/