繁体   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