還記得我之前的《Linux進(jìn)程間通信實(shí)現(xiàn)原理(1)》這篇文章嗎?,續(xù)篇來(lái)了來(lái)了,不好意思久等了大家。今天我們繼續(xù)來(lái)講Linux進(jìn)程間通信實(shí)現(xiàn)原理系列。先簡(jiǎn)單的回顧下。
簡(jiǎn)單回顧應(yīng)用程序在運(yùn)行起來(lái)之后(進(jìn)程),是相互獨(dú)立的,都有自己的進(jìn)程地址空間。但是往往在一些業(yè)務(wù)上需要進(jìn)程間的通信,來(lái)完成系統(tǒng)的某個(gè)完整的功能。我們來(lái)看下進(jìn)程間通信能干那些事情?如下: 數(shù)據(jù)傳輸。一個(gè)進(jìn)程需要發(fā)送數(shù)據(jù)到另一個(gè)進(jìn)程,這種需求肯定是存在的。 共享數(shù)據(jù)。如果有多個(gè)進(jìn)程想要訪問(wèn)數(shù)據(jù),一個(gè)進(jìn)程修改了內(nèi)容,另一個(gè)進(jìn)程能夠立即看到內(nèi)容變化。 資源保護(hù):上面的的操作中存在競(jìng)爭(zhēng)情況,內(nèi)核需要提供鎖和同步機(jī)制。 通知:一個(gè)進(jìn)程需要向另一個(gè)進(jìn)程發(fā)送消息,通知發(fā)生了某個(gè)事件。 控制:有些進(jìn)程需要控制另一個(gè)進(jìn)程的運(yùn)行。典型的例子就是gdb,可參考之前文章【gdb到底是怎么實(shí)現(xiàn)的?】
進(jìn)程間的通信方式一般可以分為八種,如下: 
我們今天主題就是來(lái)深入剖析下內(nèi)存映射的實(shí)現(xiàn)原理。 內(nèi)存映射我記得在我之前的文章中講過(guò)一次內(nèi)存映射的實(shí)現(xiàn)原理,不知道各位還記不記的。今天為什么還要講呢?主要是上一次講的還不夠深入。先給個(gè)圖各位回憶下:

這幅圖只是講解了大致的原理,接下來(lái)我們就仔細(xì)的研究下,到底是怎么實(shí)現(xiàn)的? 內(nèi)存映射實(shí)現(xiàn)原理深入剖析首先是創(chuàng)建虛擬映射區(qū)域,分為下面幾個(gè)步驟:
在當(dāng)前的虛擬地址空間中,尋找一段滿足要求大小的虛擬地址 為此虛擬地址分配一個(gè)虛擬內(nèi)存區(qū)域(vm_area_struct結(jié)構(gòu),如圖) 初始化該虛擬內(nèi)存區(qū)域 插入該虛擬內(nèi)存區(qū)域到進(jìn)程的虛擬地址區(qū)域鏈表(也是樹)中

然后是實(shí)現(xiàn)地址的映射關(guān)系(即:進(jìn)程虛擬地址空間---->>>文件磁盤地址),分為下面幾個(gè)步驟: 
依次通過(guò)待映射的文件指針,文件描述符&文件結(jié)構(gòu)體,最終調(diào)用內(nèi)核中的mmap() 內(nèi)核空間中的mmap通過(guò)虛擬文件系統(tǒng)inode模塊 定位到文件磁盤物理地址 通過(guò)remap_pfn_range()建立頁(yè)表,實(shí)現(xiàn)了文件地址和虛擬地址區(qū)域的映射關(guān)系。
到這里僅僅是創(chuàng)建了虛擬空間和映射地址,沒(méi)有任何文件數(shù)據(jù)的拷貝。真正的拷貝時(shí)刻是到了進(jìn)程發(fā)生了讀寫操作。 最后是進(jìn)程訪問(wèn)映射空間,實(shí)現(xiàn)文件內(nèi)容到物理內(nèi)存的數(shù)據(jù)拷貝,如下步驟: 進(jìn)程的讀寫操作,訪問(wèn)虛擬地址空間這一段映射地址 若進(jìn)程通過(guò)寫操作改變了其內(nèi)容,一定時(shí)間后系統(tǒng)會(huì)自動(dòng)回寫臟頁(yè)到對(duì)應(yīng)的磁盤地址,即完成了寫入文件的操作。(注意:修改時(shí),臟頁(yè)面不會(huì)立即更新,而是在之后的msync()來(lái)強(qiáng)制同步。)

總結(jié)用戶空間和內(nèi)核空間的高效交互;通過(guò)映射的區(qū)域直接交互的方式 數(shù)據(jù)拷貝次數(shù)減少;對(duì)文件的讀取操作跨過(guò)了頁(yè)緩存,減少了數(shù)據(jù)的拷貝次數(shù) 文件讀取的效率高,用內(nèi)存的讀寫方式操作IO讀寫方式 可實(shí)現(xiàn)高效的大規(guī)模數(shù)據(jù)傳輸,借助硬盤空間協(xié)助大數(shù)據(jù)操作時(shí),采用mmap可提高效率
應(yīng)用場(chǎng)景在Linux系統(tǒng)中,根據(jù)內(nèi)存映射的原理,它的應(yīng)用場(chǎng)景如下: 實(shí)現(xiàn)內(nèi)存共享:如跨進(jìn)程通信 提高數(shù)據(jù)讀寫效率;如文件讀寫操作。
|