mmap機(jī)制
在磁盤上建立一個(gè)文件,每個(gè)進(jìn)程存儲器中,單獨(dú)開辟一個(gè)空間來映射保存到實(shí)際硬盤,實(shí)際并沒有反映到主存上。
使得進(jìn)程之間通過映射同一個(gè)普通文件實(shí)現(xiàn)共享內(nèi)存,普通文件被映射到進(jìn)程地址空間后,進(jìn)程可以向訪問普通內(nèi)存一樣對文件進(jìn)行訪問,不必再調(diào)用read(),write()等操作。
- 優(yōu)點(diǎn):存儲量大
- 缺點(diǎn):讀取和寫入速度比較慢
shm機(jī)制
每個(gè)進(jìn)程的共享內(nèi)存都直接映射到實(shí)際物理存儲器上shm保存到物理存儲器(主存),實(shí)際的存儲量直接反映到主存上。
進(jìn)程間需要共享的數(shù)據(jù)被放在一個(gè)叫做IPC共享內(nèi)存區(qū)域的地方,所有需要訪問該共享區(qū)域的進(jìn)程都要把該共享區(qū)域映射到本進(jìn)程的地址空間中去。
- 優(yōu)點(diǎn):進(jìn)程間訪問速度比磁盤快
- 缺點(diǎn):存儲量不能非常大
通過shmget獲得或創(chuàng)建一個(gè)IPC共享內(nèi)存區(qū)域,并返回相應(yīng)的標(biāo)識符。
每一個(gè)共享內(nèi)存區(qū)都有一個(gè)控制結(jié)構(gòu)struct shmid_kernel。
主要API:shmget()、shmat()、shmdt()及shmctl()。
shmget()用來獲得共享內(nèi)存區(qū)域的ID,如果不存在指定的共享區(qū)域就創(chuàng)建相應(yīng)的區(qū)域。
int shmget(key_t key,size_t size,int shmflg);
key:共享內(nèi)存鍵值,可以理解為共享內(nèi)存的唯一性標(biāo)記。
size:共享內(nèi)存大小
shmflag:創(chuàng)建進(jìn)程和其他進(jìn)程的讀寫權(quán)限標(biāo)識。
返回值:相應(yīng)的共享內(nèi)存標(biāo)識符,失敗返回-1shmat()把共享內(nèi)存區(qū)域映射到調(diào)用進(jìn)程的地址空間中去,這樣,進(jìn)程就可以方便地對共享區(qū)域進(jìn)行訪問操作。
void *shmat(int shm_id,const void *shm_addr,int shmflg);
shm_id:共享內(nèi)存標(biāo)識符
shm_addr:指定共享內(nèi)存連接到當(dāng)前進(jìn)程的地址,通常為0,表示由系統(tǒng)來選擇。
shmflg:標(biāo)志位
返回值:指向共享內(nèi)存第一個(gè)字節(jié)的指針,失敗返回-1shmdt()調(diào)用用來解除進(jìn)程對共享內(nèi)存區(qū)域的映射。
shmctl實(shí)現(xiàn)對共享內(nèi)存區(qū)域的控制操作。
int shmctl(int shm_id,int command,struct shmid_ds *buf);
shm_id:共享內(nèi)存標(biāo)識符
command: 有三個(gè)值
IPC_STAT:獲取共享內(nèi)存的狀態(tài),把共享內(nèi)存的shmid_ds結(jié)構(gòu)復(fù)制到buf中。
IPC_SET:設(shè)置共享內(nèi)存的狀態(tài),把buf復(fù)制到共享內(nèi)存的shmid_ds結(jié)構(gòu)。
IPC_RMID:刪除共享內(nèi)存
buf:共享內(nèi)存管理結(jié)構(gòu)體。
ps:Python開啟多進(jìn)程使用的是multiprocessing,進(jìn)程傳遞了一個(gè)multiprocessing.Queue,使用的是shm共享內(nèi)存機(jī)制。multiprocessing模塊Value Array是基于mmap實(shí)現(xiàn)