Linux記憶體對映檔案原理詳解及實現步驟

2021-06-14 01:39:49 字數 1508 閱讀 3599

有兩種型別的記憶體對映檔案:

2.私有型,當程序建立的對映只是為讀檔案,而不是寫檔案時才會使用這種對映。出於這種目的,私有對映的效率要比共享對映的效率更高。但是對私有對映頁的任何寫操作都會使核心停止對映該檔案中的頁。因此寫操作既不會改變磁碟上的檔案,對訪問相同檔案的其他程序也是不可見的。但是私有記憶體對映中的頁會因為其他程序對檔案的修改而更新。 

記憶體對映檔案通過mmap和munmap系統呼叫來實現.

mmap呼叫實際上就是乙個記憶體物件vma的建立過程, mmap的呼叫格式是:

void * mmap(void *start, size_t length, int prot , int flags, int fd, off_t offset);

它的任何修改對其它程序都不可見. 而map_shared則無論修改與否都使用同一副本, 任何程序對頁面的修改對其它程序都是可見的.

mmap系統呼叫的實現過程是:

1.先通過檔案系統定位要對映的檔案;

2.許可權檢查, 對映的許可權不會超過檔案開啟的方式, 也就是說如果檔案是以唯讀方式開啟, 那麼則不允許建立乙個可寫對映;

3.建立乙個vma物件, 並對之進行初始化;

4.呼叫對映檔案的mmap函式, 其主要工作是給vm_ops向量表賦值;

5.把該vma鏈入該程序的vma鍊錶中, 如果可以和前後的vma合併則合併;

6.如果是要求vm_locked(對映區不被換出)方式對映, 則發出缺頁請求, 把對映頁面讀入記憶體中.

munmap(void * start, size_t length)

該呼叫可以看作是 mmap的乙個逆過程. 它將程序中從start開始length長度的一段區域的對映關閉, 如果該區域不是恰好對應乙個vma, 則有可能會分割幾個或幾個vma.

msync(void * start, size_t length, int flags):

把對映區域的修改回寫到後備儲存中. 因為munmap時並不保證頁面回寫, 如果不呼叫msync, 那麼有可能在munmap後丟失對對映區的修改. 其中flags可以是ms_sync, ms_async, ms_invalidate, ms_sync要求回寫完成後才返回, ms_async發出回寫請求後立即返回, ms_invalidate使用回寫的內容更新該檔案的其它對映. 該系統呼叫是通過呼叫對映檔案的sync函式來完成工作的.

brk(void * end_data_segement)

將程序的資料段擴充套件到end_data_segement指定的位址, 該系統呼叫和mmap的實現方式十分相似, 同樣是產生乙個vma, 然後指定其屬性. 不過在此之前需要做一些合法性檢查, 比如該位址是否大於mm->end_code, end_data_segement和mm->brk之間是否還存在其它vma等等. 通過brk產生的vma對映的檔案為空, 這和匿名對映產生的vma相似, 關於匿名對映不做進一步介紹. 庫函式malloc就是通過brk實現的.

記憶體對映檔案原理

首先,對映 這個詞,就和數學課上說的 一一對映 是乙個意思,就是建立一種一一對應關係,在這裡主要是只 硬碟上檔案 的位置與程序 邏輯位址空間 中一塊大小相同的區域之間的一一對應,如圖1中過程1所示。這種對應關係純屬是邏輯上的概念,物理上是不存在的,原因是程序的邏輯位址空間本身就是不存在的。在記憶體對...

記憶體對映檔案原理

目錄 一直都對記憶體對映檔案這個概念很模糊,不知道它和虛擬記憶體有什麼區別,而且對映這個詞也很讓人迷茫,今天終於搞清楚了。下面,我先解釋一下我對對映這個詞的理解,再區分一下幾個容易混淆的概念,之後,什麼是記憶體對映就很明朗了。首先,對映 這個詞,就和數學課上說的 一一對映 是乙個意思,就是建立一種一...

記憶體對映檔案原理

一直都對記憶體對映檔案這個概念很模糊,不知道它和虛擬記憶體有什麼區別,而且對映這個詞也很讓人迷茫,今天終於搞清楚了。下面,我先解釋一下我對對映這個詞的理解,再區分一下幾個容易混淆的概念,之後,什麼是記憶體對映就很明朗了。原理 首先,對映 這個詞,就和數學課上說的 一一對映 是乙個意思,就是建立一種一...