簡體   English   中英

如果計算機在保留內存映射文件時掛起,會發生什么情況?

[英]What happens if computer hangs while persisting a memory-mapped file?

我對使用自.NET 4.0之后可用的托管內存映射文件非常感興趣。

檢查從MSDN提取的以下語句:

持久文件是與磁盤上的源文件關聯的內存映射文件。 當最后一個過程處理完文件后,數據將保存到磁盤上的源文件中。 這些內存映射文件適用於處理非常大的源文件。

我的問題是: 如果計算機在保留內存映射文件的同時掛起,會發生什么情況?

我的意思是,由於內存映射文件存儲在虛擬內存中(我知道這在頁面文件中),因此也許可以從虛擬內存中還原文件,然后在重新啟動Windows之后嘗試將其再次存儲到源文件中。

內存映射文件基礎的數據頁位於OS緩存(文件緩存)中。 每當您關閉Windows時,它都會將所有已修改的緩存頁面寫入文件系統。

高速緩存中的頁面要么是普通文件數據(來自對文件進行讀/寫的過程),要么是由分頁系統讀取/寫入的內存映射頁面。

如果Windows無法(例如崩潰或死機)將緩存內容刷新到磁盤,則該數據將丟失。

如果啟用持久性,則重新啟動后不會刪除內存映射文件。

您可以使用帶有標志的原子動作過程來顯示數據是否有效(如果有效),您可以恢復其他數據丟失

如果您的操作系統支持(內核或文件系統生存期),例如unix,則可以使用共享內存進行同步,其同步速度比映射文件更快

現代操作系統3e(2007)預訂了內存映射文件:共享庫實際上是稱為內存映射文件的更通用工具的特例。 這里的想法是,進程可以發出系統調用以將文件映射到其虛擬地址空間的一部分。 在大多數實現中,映射時不會插入任何頁面,但是在觸摸頁面時,需要使用磁盤文件作為后備存儲一次將它們分頁。 當進程退出或顯式取消映射文件時,所有修改后的頁面都將寫回到文件中。 映射文件為I / O提供了替代模型。 無需進行讀寫操作,文件可以作為內存中的大字符數組進行訪問。 在某些情況下,程序員發現此模型更方便。 如果兩個或多個進程同時映射到同一文件,則它們可以通過共享內存進行通信。 當另一進程從其虛擬地址中映射到文件的部分虛擬地址讀取內容時,即可立即看到該進程對共享內存的寫操作。 因此,此機制在進程之間提供了高帶寬通道,並且經常被使用(甚至在映射暫存文件的范圍內)。 現在應該清楚,如果有內存映射文件可用,則共享庫可以使用此機制

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2044.html

共享內存

POSIX將共享內存對象定義為“一個表示可以同時映射到多個進程的地址空間中的內存的對象”。 共享內存類似於文件映射,並且用戶可以映射共享內存對象的多個區域,就像使用內存映射文件一樣。 在某些操作系統(如Windows)中,共享內存是文件映射的特例,其中文件映射對象訪問由系統頁面文件支持的內存。 但是,在Windows中,當連接到共享內存對象的最后一個進程關閉連接或應用程序退出時,該內存的生存期結束,因此沒有數據持久性。 如果應用程序創建共享內存,將其填充數據並退出,則數據將丟失。 此生存期稱為進程生存期。在POSIX操作系統中,共享內存的生存期有所不同,因為對於信號量,共享內存和消息隊列,必須在不再使用對象后保留對象及其狀態(包括數據,如果有的話)由任何過程引用。 對象的持久性並不意味着在系統崩潰或重新啟動后就可以保留對象的狀態,但這可以實現,因為共享內存對象實際上可以實現為永久文件系統的映射文件。 顯式調用unlink()會發生共享內存破壞,這類似於文件破壞機制。 POSIX共享內存必須具有內核生存期(對象被顯式銷毀或在操作系統重新啟動時銷毀)或文件系統持久性(共享內存對象與文件具有相同的生存期)。 此生命周期差異對於實現可移植性很重要。 許多可移植的運行時都試圖在Windows和POSIX共享內存之間實現完美的可移植性,但是本文的作者並未看到任何令人滿意的成果。 僅在進程不崩潰的情況下,將引用計數添加到POSIX共享內存中才有效,這是很常見的事情。 在Windows中無法使用本機共享內存模擬POSIX行為,因為我們可以嘗試將共享內存轉儲到文件中以獲得持久性,但是進程崩潰將避免持久性。 唯一可行的選擇是在Windows中使用內存映射文件模擬共享內存,但要盡可能避免文件內存同步。 許多其他命名的同步原語(例如命名的互斥體或信號量)也遭受相同的生存期可移植性問題。 自動共享內存清理在許多情況下都很有用,例如共享庫或DLL與其他DLL或進程進行通信。 即使發生崩潰,操作系統也會自動清理資源。 當啟動程序可以創建和填充其他進程可以讀取或修改的共享內存時,POSIX持久性也很有用。 如果服務器進程崩潰,持久性還允許恢復數據。 所有數據仍保留在共享內存中,服務器可以恢復其狀態。 本文提出了POSIX生存期(內核或文件系統生存期)作為更可移植的解決方案,但對此沒有強烈的意見。 C ++委員會應考慮這兩種方法的用例,以確定哪種行為更好,或者兩種選項是否都可用,從而迫使同時修改POSIX和Windows系統。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM