与 MemoryMappedFile 并行读写

Reading and writing in parallel to MemoryMappedFile

如果我在同一个MemoryMappedFile中并行读取和写入会发生什么?我是否有必要在阅读之前通过 Mutext 锁定它们,如 MSDN 上的示例所示?

Memory-Mapped Files

从内存映射文件创建的每个 "View" 一次只能由一个线程访问,但是您可以创建多个视图流,并且每个线程可以同时写入或读取它。

但是,如果多个视图同时尝试写入同一位置,您可能会相互获取数据 "intermixed"。示例中的互斥锁是为了防止这种混合。如果一个应用程序只写入文件而另一个只读文件,那么就不需要互斥锁,你只需要它用于多个写入器。

简短的回答是,您可能会读取损坏的数据或写入损坏的数据,并且您必须获得独占访问权限(例如 Mutex),除非读取和写入的时间恰到好处(呃!)或众所周知,它们没有命中内存映射文件的相同部分。

Consider a chunk of data at offset 100 that is 100 bytes long. A writer begins writing at offset 0 to 150, and another writes from 180 to 300. Your reader begins reading that 100 bytes while the writers are writing. What is read? What if another writer is writing from 180 to 300 at the same time. What is written? Likely, an interleaved chunk of corrupt data.

解决这个问题的经典方法是使用 reader-writer 锁。在 .NET 中,如果您在单个进程中进行并行读取和写入,则可以使用 ReaderWriterLockSlim 或更旧的 ReaderWriterLock.

如果要对多个进程执行此操作,可以使用 FileStream.Lock()FileStream.Unlock()。一个更棘手的解决方案是使用信号量和互斥量的组合。按照 this SO question 中的链接获取想法。

即使这样可能还不够。如果您的内存映射文件被您无法控制的进程(例如第三方)使用,那么您可能会损坏。上面的解决方案是合作算法的示例(所有各方都知道发生了什么并相应地采取行动)。

最笨重的方法是在打开时使用 FileShare.None 锁定整个内存映射文件。