程序間通訊機制詳解(4) 共享記憶體

2021-10-23 05:18:37 字數 2273 閱讀 5180

共享記憶體就是允許兩個或多個程序共享一定的儲存區,共享記憶體對映能夠最大限度的降低核心空間和使用者空間之間的資料拷貝,當核心空間和使用者空間存在大量資料互動時,這些程序的資料傳輸不再涉及核心,從而大大提高系統的效能,是最快的ipc形式。

當乙個程式載入進記憶體後,它被分成叫作頁的塊。每個程序都有屬於自己的程序控制塊(pcb)和位址空間(addr space),並且都有乙個與之對應的頁表,負責將程序的虛擬位址與實體地址進行對映。當乙個程式想和另外乙個程式通訊的時候,兩個不同的虛擬位址通過頁表對映到物理空間的同一區域,它們所指向的這塊區域即共享記憶體。

現階段廣泛應用於多**、graphics領域的共享記憶體方式,某種意義上不再強調對映到程序虛擬位址空間(對映的目的是能夠讓cpu訪問),而更強調以某種「控制代碼」的形式,實現跨程序訪問記憶體。

對於乙個共享記憶體,實現採用的是引用計數的原理,當程序脫離共享儲存區後,計數器減一,掛接成功時,計數器加一,只有當計數器變為零時,才能被刪除。當程序終止時,它所附加的共享儲存區都會自動脫離。

1.基於傳統sys v的共享記憶體;

2.基於posix mmap檔案對映實現共享記憶體;

3.通過memfd_create()和fd跨程序共享實現共享記憶體;

4.多**、圖形領域廣泛使用的基於dma-buf的共享記憶體。

sys v

ipcs:檢視系統中的共享儲存段

ipcrm:刪除系統中的共享儲存段

shmget (

):建立共享記憶體

shmat (

):掛接共享記憶體, 建立共享儲存段之後,將程序連線到它的位址空間

shmdt (

):去關聯共享記憶體,當乙個程序不需要共享記憶體的時候,就需要去關聯。該函式並不刪除所指定的共享記憶體區,而是將之前用shmat函式連線好的共享記憶體區脫離目前的程序。

shmctl (

):銷毀共享記憶體

posix mmap

posix提供了兩種在無親緣關係程序間共享記憶體區的方法:

(1)記憶體對映檔案:由open函式開啟,然後呼叫mmap函式把得到的描述符對映到當前程序位址空間中的乙個檔案。資料載體是物理檔案。

(2)共享記憶體區物件:先由shm_open開啟乙個posix ipc名字(也可以是檔案系統中的乙個路徑名),然後呼叫mmap將返回的描述符對映到當前程序的位址空間。資料載體是物體記憶體。 這兩種方法都需要呼叫mmap,區別在於mmap獲取描述符的手段。

一般使用共享記憶體區物件。

int

shm_open

(const

char

*name,

int oflag, mode_t mode)

;建立乙個新的共享記憶體區物件或開啟乙個已經存在的共享記憶體區物件。

intshm_unlink

(const

char

*name)

;刪除乙個共享記憶體區物件,跟其他檔案的unlink以及其他posix ipc的刪除操作一樣,物件的析構會等到該物件的所有引用全部關閉才會發生。

對映函式:mmap函式

void

*mmap

(void

*addr, size_t length,

int prot,

int flags,

int fd, off_t offset)

; 對映刪除函式munmap

intmunmap

(void

*addr, size_t length)

;從某個程序的位址空間刪除乙個對映關係。其中addr引數是由mmap返回的位址,len是對映區的大小。

注: 共享記憶體需要同步,一般與訊號量一起使用

參考:宋寶華:世上最好的共享記憶體(linux共享記憶體最透徹的一篇)

程序間通訊——共享記憶體(shared memory)

使用記憶體共享機制程序間通訊

前一篇中簡單介紹了程序間通訊的機制之一 訊息機制。本篇中我簡要的描述一下程序間通訊的另一種機制 記憶體共享機制。windows中要使用記憶體共享的方式在程序間通訊需要採用dll方式。由於win32把dll裝入全域性記憶體並把dll對映到每個程式的位址空間。所有載入dll的應用程式只能共享程式 不能共...

詳解 程序間通訊之共享記憶體

實現機制 共享記憶體時通過把一塊記憶體分別對映到不同的程序空間中實現程序間通訊。而共享記憶體本身不帶任何互斥與同步機制,但當多個程序同時對同乙個記憶體進行讀寫操作時會破壞該記憶體的內容。所以,在實際中,同步與互斥機制需要使用者來完成。include include shmget key t key,...

程序間通訊 共享記憶體

下面是自己寫的乙個簡單的共享記憶體的程序間通訊的例子。共享記憶體是用於程序間大量資料共享的一種方法。include include include include include include int main if buf1 shmat shmid,0,0 void 1 strcpy buf1,...