13

正如内存映射文件的名称所示,我知道可以使用MemoryMappedFileC# 中的类将大文件的一部分映射到内存以进行快速数据处理。我想对内存映射文件做的是并行处理内存映射。为此,我有以下问题

  1. MemoryMappedFileViewAccessor线程安全和 Parallel.For 安全吗?我实际上做了一个演示程序来测试这个问题,它似乎正在工作。但找不到任何关于此的参考。如果答案是肯定的,我就完成了。否则,
  2. 有没有办法直接访问用数组映射的内存?我知道MemoryMappedFileViewAccessor有 ReadArray 方法,但使用该方法是内存的重复。
4

3 回答 3

12

你可以推理出来。内存映射文件只是程序中的一块内存,其字节可由多个进程访问。它们在托管代码中非常尴尬,因为该块存在于特定地址。这需要使用指针访问数据,它们是托管代码中的禁忌。MemoryMappedFileViewAccessor 包装了该指针,它将数据从托管内存复制到共享内存。请注意,这违背了使用 MMF 的主要原因,以及为什么它们的支持需要这么长时间才出现在 .NET 中。确保您不想改用命名管道。

因此,推论出这一点,MMF 在设计上肯定不是线程安全的,因为这是共享内存,就像代码中的全局变量一样。如果线程读取和写入共享内存的同一部分,事情会以完全相同的方式出错。而且您还必须防止完全相同的情况,一个锁以确保只有一个线程可以访问共享部分。

另请注意,您需要在读取和写入 MMF 的进程之间实现该锁定。这往往会很痛苦,您必须使用“主”进程创建的命名互斥锁并打开“从属”进程。您不能忽略该锁定要求。值得注意的是,您从未在您的问题中提到过要解决这个问题,所以那里有红旗。

在一个进程中,不访问 MMF 同一部分的线程不能相互干扰。就像访问不同变量的两个线程不需要任何同步一样。只要他们持有确保另一个进程无法写入该部分的互斥锁。请注意,这可能意味着您想使用 Semaphore 来保护 MMF 访问,Mutex 只能由一个线程获取。

于 2013-05-03T22:32:54.977 回答
2

在内部,MemoryMappedViewAccessor 派生自 UnmanagedMemoryAccessor,虽然没有只读字段,但它看起来是不可变的——至少它不会在读/写操作期间修改现有字段,这使其成为线程安全的。反过来,它从SafeBuffer类中读取内存映射文件数据,该类在注释头中包含以下文本:

/* Keep the penalties for using this class small, both in terms of space 
// and time.  Having multiple threads reading from a memory mapped file
// will already require 2 additional interlocked operations.  If we add in 
// a "current position" concept, that requires additional space in memory and 
// synchronization.  Since the position in memory is often (but not always)
// something that can be stored on the stack, we can save some memory by 
// excluding it from this object.  However, avoiding the need for
// synchronization is a more significant win.  This design allows multiple
// threads to read and write memory simultaneously without locks (as long as
// you don't write to a region of memory that overlaps with what another 
// thread is accessing).

所以我的猜测是内存映射文件的操作是线程安全的,尽管奇怪的是在 MSDN 中没有确认这一点。

于 2013-05-03T20:28:53.020 回答
0

1) MSDN 声明MemoryMappedFile两者MemoryMappedViewAccessor

此类型的任何公共静态(在 Visual Basic 中为 Shared)成员都是线程安全的。不保证任何实例成员都是线程安全的。

2) MemoryMappedFile 的重点不是减少内存分配。如果您从磁盘读取文件,则必须分配内存来存储从文件中读取的项目。内存映射文件也是如此

于 2013-05-03T21:10:18.280 回答