如果计算机在持久存储映射文件时挂起会发生什么?

时间:2015-06-23 19:29:16

标签: c# .net .net-4.0 crash memory-mapped-files

我对使用托管内存映射文件available since .NET 4.0非常感兴趣。

检查从MSDN中提取的以下语句:

  

持久文件是与a关联的内存映射文件   磁盘上的源文件。当最后一个进程完成后   该文件,数据保存到磁盘上的源文件中。这些   内存映射文件适合使用非常大的文件   源文件。

我的问题是:如果计算机在保留内存映射文件时挂起会发生什么?

我的意思是,由于内存映射文件存储在虚拟内存中(我知道这是在页面文件中),也许可以从虚拟内存中恢复文件并尝试在重新启动Windows后再次将其存储到源文件中

2 个答案:

答案 0 :(得分:0)

作为内存映射文件基础的数据页驻留在OS缓存(文件缓存)中。每当您关闭Windows时,它都会将所有已修改的缓存页面写入文件系统。

缓存中的页面是普通文件数据(来自对文件进行读/写的进程)或内存映射页面,这些页面由分页系统读取/写入。

如果Windows无法(例如崩溃或冻结)将缓存内容刷新到磁盘,则该数据将丢失。

答案 1 :(得分:0)

如果启用持久性,则重新启动后不会删除内存映射文件。

您可以使用带有标志的原子操作流程,该标志显示数据是否有效,如果有效则可以恢复其他数据丢失

如果您的操作系统支持(内核或文件系统生命周期),如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系统。