2011-09-02 72 views
18

我有相關的處理文件,並將其映射(mmap)以下問題:寫入文件和映射內存之間有什麼區別?

  1. 我們知道,如果我們創建了一個文件,並寫入該文件,然後要麼方面,我們都是寫入存儲器。那麼爲什麼使用mmap將該文件映射到內存然後寫入?
  2. 如果是因爲我們使用mmap-PROT_NONE,PROT_READ,PROT_WRITE來實現保護,那麼使用文件也可以實現相同的保護等級。 O_RDONLYO_RDWR等。那麼,爲什麼mmap
  3. ,有什麼特別的優勢,我們得到的文件映射到內存中,然後使用它嗎?而不是隻創建一個文件並寫入它?
  4. 最後,假設我們mmap文件到內存中,如果我們寫的MMAP返回的內存位置,它同時也寫入該文件呢?

請幫我回復所有的查詢。

非常感謝。

*編輯:線程之間共享文件*

據我知道,如果我們兩個線程(不處理)之間共享文件,那麼它是明智的mmap到內存中,然後使用它,而不是直接使用該文件。

但我們知道,使用文件手段,它肯定是在主內存中,然後再爲什麼線程需要被mmaped?

回答

13

內存映射文件實際上是部分或全部映射到內存(RAM)中,而您寫入的文件將寫入內存然後刷新到磁盤。內存映射文件從磁盤中取出並明確放入內存以供讀取和/或寫入。它保持在那裏直到你取消映射。

訪問磁盤速度較慢,所以當你寫入一個文件時,它將被刷新到磁盤並不再駐留在RAM中,這意味着下次你需要該文件時,你可能會得到它來自磁盤(慢),而在內存映射文件中,您知道該文件在RAM中,並且您可以在磁盤上訪問該文件。

此外,mememory映射文件通常用作IPC機制,因此兩個或多個進程可以輕鬆共享相同的文件並對其進行讀/寫。 (使用必要的sycnh機制)

當你需要經常讀取一個文件,並且這個文件很大時,將它映射到內存中可能是有利的,這樣你可以更快地訪問它,然後打開它並每次都從磁盤獲取它。

編輯:

要看你的需求,當你有需要可以由不同的線程頻繁訪問的文件,然後我不知道該內存映射文件將必然這是一個好主意,從這樣的觀點來看,如果你希望寫入這個mmap的文件,你需要在不同線程的同一個地方同步訪問這個mmap的文件。如果這種情況經常發生,它可能成爲資源爭奪的場所。

剛剛從文件中讀取,這可能是一個很好的解決方案,因爲您不需要同步訪問,如果您只是從多線程讀取。你開始寫作的那一刻,你必須使用同步機制

我建議,如果您必須寫入文件,就像您使用其他文件一樣,每個線程都以本地方式以線程方式執行自己的文件訪問。這樣就減少了線程同步的需求,並且很難找到和調試錯誤的可能性。

+0

那麼我們收到的優勢是什麼? – kingsmasher1

+0

@ kingsmasher1編輯我的回答 –

+0

我已經添加了一個編輯,你能幫我一下嗎? – kingsmasher1

1
  1. 其中一個原因可能是設置爲寫入數據緩衝區中,然後該緩衝區寫入在一端轉到文件,你有(遺留)代碼。在這種情況下,使用mmap將至少保存一份數據,因爲操作系統可以直接將緩衝區寫入磁盤。 只要是關於文件寫作,我還不能想象爲什麼你想要使用mmap的任何其他原因。

  2. 不,這裏的保護不相關我會說。

  3. 它可以保存一個或兩個數據副本,例如,應用程序緩衝區到libc緩衝區到OS緩衝區,請參閱第1點。這可能會在寫入大量數據時產生性能差異。

  4. 號據我所知,OS是免費的,在它喜歡的任何時間寫數據時,只要在該存儲區域msyncmunmap通話結束後,數據被寫入磁盤。 (對於大多數文件來說,在大多數情況下,由於執行原因,它可能不會寫入任何內容:將整個塊寫入磁盤,因爲更改一個字節非常昂貴,特別是如果可以預料到更多對塊的修改將在不久的將來發生。)

+0

根據你的觀點4:你的意思是,如果程序正常退出,那麼mmap副本和文件副本將是相同的。對? – kingsmasher1

+0

基本上是這樣的:如果程序編碼正確並且在munmap退出之前調用munmap,那麼文件的內容將是相同的。 – Tobi

+0

@ kingsmasher1:不完全相同,只是一樣而已。 –

2

1)您誤解了write(2)系統調用。 write()不會寫入,它只是將緩衝區內容複製到OS緩衝區鏈並將其標記爲髒。其中一個操作系統線程(bdflush IIRC)將會讀取這些緩衝區,將它們寫入磁盤並擺弄一些標誌。後來。 使用mmap,你可以直接訪問OS緩衝區(但是如果你改變它的內容,它也會被標記爲髒)

2)這不是關於保護,而是關於在pagetable條目中設置標誌。 3)你避免了雙重緩衝。你也可以用字符來代替文件,而不是塊,這有時更實用

4)它是你一直使用的系統緩衝區(掛鉤到你的地址空間)。系統可能會或可能不會將其中的一部分寫入磁盤。

5)如果線程屬於同一進程並共享頁面表和地址空間,那麼是的。

0

在大多數情況下,您應該將內存映射文件視爲您使用的內存。您應該只關心特殊情況,如同步光盤。它與存儲器是同一種存儲器,但可以從文件初始化並隨時存儲到文件中。

相關問題