深入理解共享記憶體機制

2021-08-04 08:15:17 字數 2446 閱讀 8418

共享記憶體可以說是最有用的程序間通訊方式,也是最快的ipc形式。是針對其他通訊機制執行效率較低而設計的。兩個不同程序a、b共享記憶體的意思是,同一塊物理記憶體被對映到程序a、b各自的程序位址空間。程序a可以即時看到程序b對共享記憶體中資料的更新,反之亦然。由於多個程序共享同一塊記憶體區域,必然需要某種同步機制,互斥鎖和訊號量都可以。

採用共享記憶體通訊的乙個顯而易見的好處是效率高,因為程序可以直接讀寫記憶體,而不需要任何資料的拷貝。對於像管道和訊息佇列等通訊方式,則需要在核心和使用者空間進行四次的資料拷貝,而共享記憶體則只拷貝兩次資料[1]:一次從輸入檔案到共享記憶體區,另一次從共享記憶體區到輸出檔案。實際上,程序之間在共享記憶體時,並不總是讀寫少量資料後就解除對映,有新的通訊時,再重新建立共享記憶體區域。而是保持共享區域,直到通訊完畢為止,這樣,資料內容一直儲存在共享記憶體中,並沒有寫回檔案。共享記憶體中的內容往往是在解除對映時才寫回檔案的。因此,採用共享記憶體的通訊方式效率是非常高的。

系統v共享記憶體原理

程序間需要共享的資料被放在乙個叫做ipc共享記憶體區域的地方,所有需要訪問該共享區域的程序都要把該共享區域對映到本程序的位址空間中去。系統v共享記憶體通過shmget獲得或建立乙個ipc共享記憶體區域,並返回相應的識別符號。核心在保證shmget獲得或建立乙個共享記憶體區,初始化該共享記憶體區相應的shmid_kernel結構體的同時,還將在特殊檔案系統shm中,建立並開啟乙個同名檔案,並在記憶體中建立起該檔案的相應dentry及inode結構,新開啟的檔案不屬於任何乙個程序(任何程序都可以訪問該共享記憶體區)。所有這一切都是系統呼叫shmget完成的。

注:每乙個共享記憶體區都有乙個控制結構struct shmid_kernel,shmid_kernel是共享記憶體區域中非常重要的乙個資料結構,它是儲存管理和檔案系統結合起來的橋梁,定義如下:

正如訊息佇列和訊號燈一樣,核心通過資料結構struct ipc_ids shm_ids維護系統中的所有共享記憶體區域。上圖中的shm_ids.entries變數指向乙個ipc_id結構陣列,而每個ipc_id結構陣列中有個指向kern_ipc_perm結構的指標。到這裡讀者應該很熟悉了,對於系統v共享記憶體區來說,kern_ipc_perm的宿主是 shmid_kernel結構,shmid_kernel是用來描述乙個共享記憶體區域的,這樣核心就能夠控制系統中所有的共享區域。同時,在 shmid_kernel結構的file型別指標shm_file指向檔案系統shm中相應的檔案,這樣,共享記憶體區域就與shm檔案系統中的檔案對應起來。

在建立了乙個共享記憶體區域後,還要將它對映到程序位址空間,系統呼叫shmat()完成此項功能。由於在呼叫shmget()時,已經建立了檔案系統 shm中的乙個同名檔案與共享記憶體區域相對應,因此,呼叫shmat()的過程相當於對映檔案系統shm中的同名檔案過程,原理與mmap()大同小異。

系統v共享記憶體api

標頭檔案:

#include

#include

shmget()用來獲得共享記憶體區域的id,如果不存在指定的共享區域就建立相應的區域。shmat()把共享記憶體區域對映到呼叫程序的位址空間中去,這樣,程序就可以方便地對共享區域進行訪問操作。shmdt()呼叫用來解除程序對共享記憶體區域的對映。shmctl實現對共享記憶體區域的控制操作。

系統v共享記憶體限制

在/proc/sys/kernel/目錄下,記錄著系統v共享記憶體的一下限制,如乙個共享記憶體區的最大位元組數shmmax,系統範圍內最大共享記憶體區識別符號數shmmni等,可以手工對其調整,但不推薦這樣做。

系統v共享記憶體範例

/***** testwrite.c *******/

#include

#include

#include

#include

typedef struct people;

main(int argc, char** argv)

p_map=(people*)shmat(shm_id,null,0);

temp='a';

for(i = 0;i<10;i++)

if(shmdt(p_map)==-1)

perror(" detach error ");

}/********** testread.c ************/

#include

#include

#include

#include

typedef struct people;

main(int argc, char** argv)

p_map = (people*)shmat(shm_id,null,0);

for(i = 0;i<10;i++)

if(shmdt(p_map) == -1)

perror(" detach error ");

}

深入理解Linux記憶體管理機制(一)

一 記憶體組織 計算機記憶體屬於隨機儲存器 ram 目前pc機廣泛使用的是ddr sdram,即 雙倍速率同步動態隨機儲存器 其本質上仍然是由n bits m kb個記憶體晶元組成的,比如如果我們需要8位64kb的記憶體,則我們就需要2 8 16塊4bits 8kb的記憶體塊。由於計算機通常是以位元...

深入理解Linux記憶體管理機制(一)

深入理解linux記憶體管理機制 一 通過本文,您即可以 1.儲存器硬體結構 2.分段以及對應的組織方式 3.分頁以及對應的組織方式。注1 本文以linux核心2.6.32.59本版為例,其對應的 可以在 找到。注2 本文所有的英文專有名詞都是我隨便翻譯的,請對照英文原文進行理解。注3 推薦使用so...

深入理解Linux記憶體管理機制(一)

深入理解linux記憶體管理機制 一 通過本文,您即可以 1.儲存器硬體結構 2.分段以及對應的組織方式 3.分頁以及對應的組織方式 注1 本文以linux核心2.6.32.59本版為例,其對應的 可以在 找到。注2 本文所有的英文專有名詞都是我隨便翻譯的,請對照英文原文進行理解。注3 推薦使用so...