与 MemoryMappedFile 并行读写
Posted
技术标签:
【中文标题】与 MemoryMappedFile 并行读写【英文标题】:Reading and writing in parallel to MemoryMappedFile 【发布时间】:2015-07-30 14:23:32 【问题描述】:如果我在同一个MemoryMappedFile
中并行读写会发生什么?是否有必要在阅读之前通过Mutext
锁定它们,如 MSDN 上的示例所示?
Memory-Mapped Files
【问题讨论】:
如何写入文件? 文件本身当然可以同时写入,单个访问器是"not guaranteed to be thread safe." 我想通过BinaryWriter
从一个应用程序写入,并通过BinaryReader
从另一个应用程序读取。
您是否尝试使用内存映射文件作为某种进程通信?
这绝对可以。我相信在示例中使用Mutex
只是为了同步演示流程的工作;否则,在写入者开始写入任何数据之前,读取过程可能已经终止。裸数据交换不需要同步,尽管您通常希望在数据准备好读取或写入时以某种方式发出信号。
【参考方案1】:
从内存映射文件创建的每个“视图”一次只能由一个线程访问,但是您可以创建多个视图流,并且每个线程可以同时对其进行写入或读取。
但是,如果多个视图尝试同时写入同一位置,您可能会得到相互“混合”的数据。示例中的互斥锁是为了防止这种混合。如果一个应用程序只写入文件而另一个应用程序只读取,则不需要互斥锁,您只需要多个写入器。
【讨论】:
这是需要的提示:`如果一个应用程序只写入文件而另一个应用程序只读取,则不需要互斥锁,您只需要多个写入器。` 谢谢!【参考方案2】:简短的回答是,您可能会读取损坏的数据或写入损坏的数据,并且您必须获得独占访问权限(例如Mutex
),除非读取和写入的时间安排得当(呃!)或者已知它们是'没有碰到内存映射文件的相同部分。
考虑在偏移量 100 处有 100 个字节长的数据块。一个写入器从偏移量 0 到 150 开始写入,另一个写入从 180 到 300。您的读取器在写入器写入时开始读取这 100 个字节。什么是阅读?如果另一位作家同时写 180 到 300 篇怎么办。写什么?很可能是一块交错的损坏数据。
解决这个问题的经典方法是使用读写锁。在 .NET 中,如果您在单个进程中进行并行读取和写入,则可以使用 ReaderWriterLockSlim
或更旧的 ReaderWriterLock
。
如果您想对多个进程执行此操作,您可以使用FileStream.Lock()
和FileStream.Unlock()
。一个更棘手的解决方案是使用信号量和互斥体的组合。按照this SO question 的链接获取想法。
即使这样可能还不够。如果您的内存映射文件被您无法控制的进程(例如第三方)使用,那么您可能会受到损坏。上述解决方案是协作算法的示例(所有各方都知道发生了什么并采取相应的行动)。
最笨拙的方法是在使用FileShare.None
打开时锁定整个内存映射文件。
【讨论】:
以上是关于与 MemoryMappedFile 并行读写的主要内容,如果未能解决你的问题,请参考以下文章