內(nèi)存映射
內(nèi)存映射指的是將 : 進(jìn)程中的1個(gè)虛擬內(nèi)存區(qū)域 & 1個(gè)磁盤上的對(duì)象该押,使得二者存在映射關(guān)系筒主。當(dāng)然撕捍,也可以多個(gè)進(jìn)程同時(shí)映射到一個(gè)對(duì)象上面迈嘹。
實(shí)現(xiàn)過(guò)程
- 內(nèi)存映射的實(shí)現(xiàn)過(guò)程主要是通過(guò)Linux系統(tǒng)下的系統(tǒng)調(diào)用函數(shù):mmap()
- 該函數(shù)的作用 = 創(chuàng)建虛擬內(nèi)存區(qū)域 + 與共享對(duì)象建立映射關(guān)系
- 其函數(shù)原型全庸、具體使用 & 內(nèi)部流程 如下
/** * 函數(shù)原型 */
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
/**
* 具體使用(用戶進(jìn)程調(diào)用mmap())
* 下述代碼即常見(jiàn)了一片大小 = MAP_SIZE的接收緩存區(qū) & 關(guān)聯(lián)到共享對(duì)象中(即建立映射)
*/
mmap(NULL, MAP_SIZE, PROT_READ, MAP_PRIVATE, fd, 0);
/**
* 內(nèi)部原理
* 步驟1:創(chuàng)建虛擬內(nèi)存區(qū)域
* 步驟2:實(shí)現(xiàn)地址映射關(guān)系,即:進(jìn)程的虛擬地址空間 ->> 共享對(duì)象
* 注:
* a. 此時(shí)融痛,該虛擬地址并沒(méi)有任何數(shù)據(jù)關(guān)聯(lián)到文件中壶笼,僅僅只是建立映射關(guān)系
* b. 當(dāng)其中1個(gè)進(jìn)程對(duì)虛擬內(nèi)存寫(xiě)入數(shù)據(jù)時(shí),則真正實(shí)現(xiàn)了數(shù)據(jù)的可見(jiàn)
*/
優(yōu)點(diǎn)
進(jìn)程在讀寫(xiě)磁盤的時(shí)候雁刷,大概的流程是:
以write 為例:
進(jìn)程(用戶空間) -> 系統(tǒng)調(diào)用覆劈,進(jìn)入內(nèi)核 -> 將要寫(xiě)入的數(shù)據(jù)從用戶空間拷貝到內(nèi)核空間的緩存區(qū) -> 調(diào)用磁盤驅(qū)動(dòng) -> 寫(xiě)在磁盤上面。
使用mmap之后
進(jìn)程(用戶空間)--> 讀寫(xiě)映射的內(nèi)存 --> 寫(xiě)在磁盤上面沛励。
(這樣的優(yōu)點(diǎn)是 避免了頻繁的進(jìn)入內(nèi)核空間责语,進(jìn)行系統(tǒng)調(diào)用,提高了效率)
共享內(nèi)存
共享內(nèi)存是一種ipc的方式目派,用于進(jìn)程通信坤候。共享內(nèi)存位于 進(jìn)程空間的 棧和堆之間。一般默認(rèn)的大小是32M企蹭。
實(shí)現(xiàn)api
shmget 函數(shù)