liunx ipc 共享記憶體

2021-10-23 23:05:52 字數 3617 閱讀 9881

共享記憶體是liunx平台的一種ipc機制,不同程序可以對同一塊記憶體進行讀寫,由於所有程序對共享記憶體的訪問就和訪問自己的記憶體空間一樣,而

不需要進行額外系統呼叫或核心操作,同時還避免了多餘的記憶體拷貝,所以,這種方式是效率最高、速度最快的程序間通訊方式。共享記憶體和

android中binder的通訊機制相比,避免了一次copy操作。一般對於共享記憶體的操作為了避免程序之間的紊亂,會配合使用類似訊號量等別的機制

加以訪問限制訪問順序。

我們知道共享記憶體的申請最後都會轉換到真正的物理記憶體,而這個對應關係如下,簡單的理解就是程序a申請一塊物理記憶體,然後將其對映到這塊物理記憶體上,然後程序b也將自己對映到這塊物理記憶體上,然後他們對這塊記憶體的操作就完成了跨程序操作。

函式定義如下:

#include

#include

#include

key_t ftok

(const

char

*pathname,

int proj_id)

;函式ftok用於建立乙個關鍵字,可以用該關鍵字關聯乙個共享記憶體段。

引數pathname為乙個全路徑檔名,並且該檔案必須可訪問。

引數proj_id通常傳入一非0字元

通過pathname和proj_id組合可以建立唯一的key

如果呼叫成功,返回一關鍵字,否則返回-

1int

shmget

(key_t key,

int size,

int shm***)

;函式shmget用於建立或開啟一共享記憶體段,該記憶體段由函式的第乙個引數唯一建立。函式成功,則返回乙個唯一的共享記憶體標識號(相當於程序號,唯一的標識著共享記憶體),失敗返回-

1。引數key是乙個與共享記憶體段相關聯關鍵字,如果事先已經存在乙個與指定關鍵字關聯的共享記憶體段,則直接返回該記憶體段的標識,表示開啟,如果不存在,則建立乙個新的共享記憶體段。key的值既可以用ftok函式產生,也可以是ipc_rpivate(用於建立乙個只屬於建立程序的共享記憶體,主要用於父子通訊),表示總是建立新的共享記憶體段;

引數size指定共享記憶體段的大小,以位元組為單位;

引數shm***是一掩碼合成值,可以是訪問許可權值與(ipc_creat或ipc_excl)的合成。ipc_creat表示如果不存在該記憶體段,則建立它。ipc_excl表示如果該記憶體段存在,則函式返回失敗結果(-1

)。如果呼叫成功,返回記憶體段標識,否則返回-

1void

*shmat

(int shmid,

const

void

*shmaddr,

int shm***)

;函式shmat將共享記憶體段對映到程序空間的某一位址。

引數shmid是共享記憶體段的標識 通常應該是shmget的成功返回值

引數shmaddr指定的是共享記憶體連線到當前程序中的位址位置。通常是null,表示讓系統來選擇共享記憶體出現的位址。

引數shm***是一組位標識,通常為0即可。

如果呼叫成功,返回對映後的程序空間的首位址,否則返回(

char*)

-1。int

shmdt

(const

void

*shmaddr)

;函式shmdt用於將共享記憶體段與程序空間分離。

引數shmaddr通常為shmat的成功返回值。

函式成功返回0,失敗時返回-

1.注意,將共享記憶體分離並沒刪除它,只是使得該共享記憶體對當前程序不在可用。

intshmctl

(int shmid,

int cmd,

struct shmid_ds *buf)

;函式shmctl是共享記憶體的控制函式,可以用來刪除共享記憶體段。

引數shmid是共享記憶體段標識 通常應該是shmget的成功返回值

引數cmd是對共享記憶體段的操作方式,可選為ipc_stat,ipc_set,ipc_rmid。通常為ipc_rmid,表示刪除共享記憶體段。

引數buf是表示共享記憶體段的資訊結構體資料,通常為null。

例如shmctl

(ksharemem,ipc_rmid,

null

)表示刪除調共享記憶體段kharemem

share_a.cpp

#include

#include

#include

#include

#include

#include

#include

intmain

(int

*argc,

char

*ar**)

//3,將共享記憶體段對映到程序空間的某一位址,返回映程序射空間的首位址

pstr =

(char*)

shmat

(my_shm,

null,0

);strcpy

(pstr,

"hello world!\n");

sleep(5

);printf

("recv from 2:%s\n"

,pstr)

;//4,將共享記憶體段與程序空間分離

shmdt

(pstr)

;//5,刪除共享記憶體段

shmctl

(my_shm,ipc_rmid,

null);

return0;

}

share_b.cpp

#include

#include

#include

#include

#include

#include

#include

intmain

(int

*argc,

char

*ar**)

//3,將共享記憶體段對映到某一程序空間

pstr =

(char*)

shmat

(my_shm,

null,0

);printf

("recv from 1:%s\n"

,pstr)

;strcpy

(pstr,

"how are you!\n");

//4將共享記憶體段與程序空間分離

結合上面**可以看到,a程序申請了一塊位元組為1024的共享記憶體,先寫入「hello world」 ,然後b程序獲取這個共享記憶體讀取記憶體資料輸出「hello world」, 隨後寫入 "how are you!」,a再讀取共享記憶體的內容"how are you!」輸出。

我們可以通過ipcs -m檢視,在未執行申請共享記憶體的時候沒有大小為1024的共享記憶體,再申請之後,就出現了。

參考:

Linux共享記憶體及共享記憶體API

共享記憶體區是最快的ipc 程序間通訊 形式。用共享記憶體從伺服器拷貝檔案資料到客戶端 共享記憶體基本api include include 1.int shmget key t key,size t size,int shm 功能 用來建立共享記憶體 key 是這個共享記憶體段的名字 size 共...

mysql共享記憶體 MySQL全域性共享記憶體介紹

前言 全域性共享記憶體則主要是 mysql instance mysqld程序 以及底層儲存引擎用來暫存各種全域性運算及可共享的暫存資訊,如儲存查詢快取的 query cache,快取連線線程的 thread cache,快取表檔案控制代碼資訊的 table cache,快取二進位制日誌的 binl...

mysql共享記憶體 MySQL全域性共享記憶體介紹

前言 全域性共享記憶體則主要是 mysql instance mysqld程序 以及底層儲存引擎用來暫存各種全域性運算及可共享的暫存資訊,如儲存查詢快取的 query cache,快取連線線程的 thread cache,快取表檔案控制代碼資訊的 table cache,快取二進位制日誌的 binl...