(三)程序通訊(三) 共享記憶體

2021-09-21 14:56:04 字數 4636 閱讀 9768

目錄

28共享記憶體介紹

共享記憶體示意圖

管道、訊息佇列與共享記憶體傳遞資料對比

mmap函式

munmap函式

msync函式

29system v共享記憶體

共享記憶體資料結構

共享記憶體函式

shmge

shmat

shmdt

shmctl

共享記憶體示例

共享記憶體區是最快的ipc形式,這些程序間資料傳遞不再涉及到核心,換句話說是程序不再通過執行進入核心的系統呼叫來傳遞彼此的資料。

即每個程序位址空間都有乙個共享儲存器的對映區,當這塊區域都對映到相同的真正的實體地址空間時,可以通過這塊區域進行資料交換,例如共享庫就是這麼實現的,很多程序都會使用同乙個函式如printf,也許在真正的實體地址空間中只存在乙份printf.o ,然後所有程序都對映到這乙份printf.o 就實現了共享。

用管道或者訊息佇列傳遞資料

用共享記憶體傳遞資料:

即使用共享記憶體傳遞資料比用訊息佇列和管道來說,減少了進入核心的次數,提高了效率。

函式原型

#include void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);
函式功能

將檔案或者裝置空間對映到共享記憶體區。
返回值

成功返回對映到的記憶體區的起始位址;失敗返回-1
引數說明

/*

addr: 要對映的起始位址,通常指定為null,讓核心自動選擇

len:對映到程序位址空間的位元組數

prot:對映區保護方式

flags:標誌

fd:檔案描述符

offset:從檔案頭開始的偏移量,必須是頁大小的整數倍(在32位體系統結構上通常是4k)

*/

/*

prot 引數取值:

prot_exec 表示對映的這一段可執行,例如對映共享庫

prot_read 表示對映的這一段可讀

prot_write 表示對映的這一段可寫

prot_none 表示對映的這一段不可訪問

*/

/*

flag引數有很多種取值,這裡只講兩種,其它取值可檢視mmap(2)

map_shared 多個程序對同乙個檔案的對映是共享的,乙個程序對對映的記憶體做了修改,另乙個程序也會看到這種變化。

map_private 多個程序對同乙個檔案的對映不是共享的,乙個程序對對映的記憶體做了修改,另乙個程序並不會看到這種變化,也不會真的寫到檔案中去。

*/

記憶體對映檔案示意圖:

mmap 程式設計注意點:

函式原型

int munmap(void *addr, size_t len);
函式功能

取消mmap函式建立的對映
返回值

成功返回0;失敗返回-1
引數說明

addr: 對映的記憶體起始位址

len:對映到程序位址空間的位元組數

函式原型

函式功能

返回值引數說明

struct shmid_ds ;
同樣地,第乙個成員是共有的ipc核心資料結構,其餘是私有成員。

函式原型

#include #include int shmget(key_t key, size_t size, int shm***);
函式功能

用來建立共享記憶體
返回值

成功返回乙個非負整數,即該共享記憶體段的標識碼;失敗返回-1
引數說明

key:這個共享記憶體段名字

size:共享記憶體大小

shm***:由九個許可權標誌構成,它們的用法和建立檔案時使用的mode模式標誌是一樣的

函式原型

void *shmat(int shmid, const void *shmaddr, int shm***);
函式功能

將共享記憶體段連線到程序位址空間
返回值

成功返回乙個指標,指向共享記憶體第乙個位元組;失敗返回-1
引數說明

shmid: 共享記憶體標識

shmaddr:指定連線的位址

shm***:它的兩個可能取值是shm_rnd和shm_rdonly

/*

shmaddr為null,核心自動選擇乙個位址

shmaddr不為null且shm***無shm_rnd標記,則以shmaddr為連線位址。

shmaddr不為null且shm***設定了shm_rnd標記,則連線的位址會自動向下調整為shmlba的整數倍。

公式:shmaddr - (shmaddr % shmlba)

shm***=shm_rdonly,表示連線操作用來唯讀共享記憶體

*/

函式原型

int shmdt(const void *shmaddr);
函式功能

將共享記憶體段與當前程序脫離
返回值

成功返回0;失敗返回-1
引數說明

shmaddr: 由shmat所返回的指標

注意:將共享記憶體段與當前程序脫離不等於刪除共享記憶體段

函式原型

int shmctl(int shmid, int cmd, struct shmid_ds *buf);
函式功能

用於控制共享記憶體
返回值

成功返回0;失敗返回-1
引數說明

shmid:由shmget返回的共享記憶體標識碼

cmd:將要採取的動作(有三個可取值)

buf:指向乙個儲存著共享記憶體的模式狀態和訪問許可權的資料結構

/*

cmd 的取值如下,與訊息佇列類似:

ipc_stat 把shmid_ds結構中的資料設定為共享記憶體的當前關聯值

ipc_set 在程序有足夠許可權的前提下,把共享記憶體的當前關聯值設定為shmid_ds資料結構中給出的值

ipc_rmid 刪除共享記憶體段

*/

shm_write.c

#include#include#include#include#include#include#include#include#include#include#include#include#include#define err_exit(m) \

do  while(0)

typedef struct stu

stu;

int main(int argc, char *ar**)

shm_read.c

#include#include#include#include#include#include#include#include#include#include#include#include#include#define err_exit(m) \

do  while(0)

typedef struct stu

stu;

int main(int argc, char *ar**)

程序間通訊 三 共享記憶體

共享記憶體是linux下倆程序通訊的一種方式,主要功能是讓兩個程序的虛擬位址都對映到同一片實體地址上,就可以通過這片實體地址進行資料的互動 mmap函式要求核心建立乙個新的虛擬記憶體區域,最好是從位址start開始的乙個區域,並將檔案描述符df指定的物件的乙個連續的片對映到這個新的區域,連續的物件片...

程序間通訊(三) 共享記憶體

共享記憶體區是最快的ipc形式。一旦這樣的記憶體對映到共享他的程序的位址空間,這些程序間資料傳遞不再涉及到核心,換句話說就是程序不再通過執行進入核心的系統呼叫來傳遞彼此的資料。共享記憶體示意圖 共享記憶體資料結構 struct shmid ds 相關函式shmget函式 建立共享記憶體 int sh...

Linux 程序間通訊(三) 共享記憶體

1.共享記憶體 共享記憶體方式可以在多個程序直接共享資料,因為其直接使用記憶體,不要多餘的拷貝,是速度最快的ipc方式 共享記憶體有兩種實現方式,使用mmap和shm方式,如下圖 1 mmap方式是將檔案與程序位址空間進行對映,對實際物理記憶體影響小 2 shm方式是將每個程序的共享記憶體與實際物理...