我需要一個非複製的非常大的mmap文件的重新大小,同時仍允許併發訪問讀者線程。快速調整mmap文件的大小
簡單的方法是在相同的文件上使用兩個MAP_SHARED映射(增長文件,然後創建包含增長區域的第二個映射),然後取消映射舊映射,一旦所有可以訪問它的讀取器完成。但是,我很好奇下面的方案是否可行,如果是的話,它是否有優勢。
- MMAP與MAP_PRIVATE 文件
- 做只讀在多線程
- 要麼獲得該文件的互斥這個內存訪問,寫入內存(假設這在某種程度上將完成讀取器可能讀取的內存不會被它搞砸)
- 或獲取互斥鎖,但增加文件的大小並使用mremap將其移動到新地址(調整映射的大小而不復制或不必要的文件IO)
瘋狂的部分進來(4)。如果移動內存,則舊地址將變爲無效,而仍在讀取它的讀者可能突然出現訪問衝突。如果我們修改讀取器來捕獲這個訪問衝突,然後重新開始操作(即不重新讀取錯誤的地址,重新計算給定偏移量的地址和mremap中的新基址)。是的,我知道這是邪惡的,但在我看來,讀者只能成功讀取舊地址處的數據,或者因訪問衝突而重試失敗。如果足夠小心,那應該是是安全的。由於重新調整大小不會經常發生,讀者最終會成功,而不會陷入重試循環。
如果舊地址空間重新使用,而閱讀器仍然有指向它的指針,則可能會出現問題。然後將不會有訪問衝突,但數據將不正確,程序進入未定義行爲的獨角獸和糖果填充的土地(其中通常既不是獨角獸也不是糖果)。
但是,如果您完全控制了分配並且可以確保在此期間發生的任何分配都不會重複使用舊的地址空間,那麼這應該不成問題,行爲不應該是未定義的。
我對不對?這可以工作嗎?使用兩個MAP_SHARED映射有沒有什麼好處?
您可以只使用讀寫鎖定並保護寫入鎖定下的重新映射,沒有? – fge 2012-01-02 18:01:56
我猜測瓶頸是磁盤。你確定這是值得的麻煩嗎?從磁盤複製大文件總是需要時間,因爲磁盤是慢速的機械設備。 – 2012-01-02 18:03:03
fge,是的,但在這種情況下鎖定讀線程是不可能的 – Eloff 2012-01-02 18:07:17