C# 内存映射文件使用情况

C# 内存映射文件使用情况,c#,C#,我目前正试图了解内存映射文件,并可能在我的应用程序中实现它们 应用程序使用一系列大型输入文件来查找位置-当应用程序在单个线程上使用时,每个文件都会按顺序访问,我猜这会进入更随机的访问区域-这使得MMF看起来很有价值 然而,我对使用有点困惑-我应该在每个线程中更新MMF吗?我知道他们可以共享同一个底层文件,所以看起来我希望所有线程都使用相同的文件,然后只需在每个线程上创建一个MMF视图 如果我应该只为每个文件创建一个MMF,是否有方法测试MMF是否已经创建-通过已分配的名称或其他方式,以防止尝试打

我目前正试图了解内存映射文件,并可能在我的应用程序中实现它们

应用程序使用一系列大型输入文件来查找位置-当应用程序在单个线程上使用时,每个文件都会按顺序访问,我猜这会进入更随机的访问区域-这使得MMF看起来很有价值

然而,我对使用有点困惑-我应该在每个线程中更新MMF吗?我知道他们可以共享同一个底层文件,所以看起来我希望所有线程都使用相同的文件,然后只需在每个线程上创建一个MMF视图

如果我应该只为每个文件创建一个MMF,是否有方法测试MMF是否已经创建-通过已分配的名称或其他方式,以防止尝试打开同一文件的多个映射,或者我需要知道线程中将使用哪些文件,并传入已创建的实例以防止复制品


干杯。

一个进程的线程总是共享相同的地址空间,这意味着每个线程都可以访问整个进程的“全局”对象和资源

您需要在进程中同步对文件的访问。在每个线程中重新打开文件没有多大意义,特别是在谈论“更大”的数量(数MB)时。
提供了一篇关于您的主题的文章,希望对您有所帮助。

如果每个线程专用于一个文件,那么让每个线程为正在处理的一个文件创建自己的MMF可能是有意义的。仅由单个线程使用的资源更容易在线程内分配和销毁

但是,如果所有线程都在读取同一个文件,那么您就不想创建多个MMF,因为这样做只会增加所消耗的内存量,并产生一致性问题(文件同一部分的多个视图)

对于在同一文件上运行的多个线程,您应该创建一次MMF,并与多个线程共享MMF指针

在多线程情况下按需分配很快就会变得复杂,通常归结为对受保护资源的每次访问都需要一个锁。如果运行多个独立线程都必须排队等待访问共享资源,那么需要锁可能会很快挫败运行多个独立线程的任何性能优势

如果您可以在构建/启动线程之前分配共享资源,那么您通常不需要锁定访问资源,因为在线程需要资源时,资源总是存在的

这样,我会考虑在线程旋转之前分配MMF,并在没有锁的所有线程之间共享MMF指针。 这还假设文件是严格只读的,即多个线程永远不会写回文件或MMF。多个线程可以共享指向公共内存区域/MMF的指针,以进行只读访问,而不会出现任何线程并发问题

与传统的缓冲文件访问相比,请注意您对MMF性能的假设。如果您的整个文件数据适合可用RAM,则MMF对随机访问模式的性能可能比缓冲文件I/O更高。如果文件数据比可用RAM大得多,则缓冲文件I/O对随机访问的性能可能比使用MMF更高。为什么?因为MMF对内存的使用非常挑剔。MMF只能加载4k页面大小的数据块。缓冲文件I/O可以根据您的实际数据大小需求和模式进行更精细的调整。如果你的应用程序从文件中100个不同的位置加载512字节的数据,MMF将不得不加载4k*100=400k字节的数据,即使你只需要512*100=50k的数据。在这种数据访问模式/用例中,MMF需要的数据传输和内存消耗是传统文件I/O的10倍


MMF的主要吸引力通常是开发人员的便利性,而不是原始性能。对于开发人员来说,从MMF支持的指针读取数据通常比编写和调优面向块的文件I/O子系统更方便。使用一种技术没有什么错,因为它对开发人员来说既简单又方便,只要您承认这一事实。

MSDN文章使用了“OpenExisting”-如果您知道该文件已经存在,这一点就行了,在我的情况下,我不知道需要哪些文件。有没有办法测试文件是否已经打开?关于这一点,您需要使用FileStream.Open()进行检查。是来自SO的条目。感谢您的完整回答!我只是在处理读取文件的问题,所以这不是一个问题,我被要求查看MMF在我的特定实例中的影响,因此我将尝试实现它,以便理解和好奇。抱歉如果我误解了,你说我最好传递一个指针,MSDN文章在创建时对给定的名称使用了“OpenExisting”-没有办法测试具有该名称的MMF是否存在吗?我不知道我将使用哪些文件,直到我已经进入线程,因为它当前已被写入,这太晚了。很抱歉指针引用-旧的Win32本机代码习惯难以改变。>我的建议是,如果所有线程都使用同一个文件,并且只读取数据,那么您可能只需要在所有线程中使用一个MMF实例。在线程启动之前调用MMF.CreateFromFile一次,并与所有线程共享该MMF对象实例——例如,将MMF对象填充到线程可以访问的静态变量中。如果您不打算使用MMF的多个视图,那么您可能还可以在所有线程中共享一个视图。在为磁盘上的同一文件构造多个MMF实例时需要小心的原因是要控制内存消耗。一个MMF.CreateFromFile加上另一个MMF.CreateFromFile fo