在进程之间同时共享内存映射

问题描述 投票:0回答:1

在克服了其他一些困难之后,我现在陷入了这个(可能很简单)的问题。

我的目标:

  • 我的应用程序的多个实例正在运行和执行 同时
  • 对同一个文件进行操作(读和写)
  • 解决方案(我想做的):使用内存映射文件来加速 执行。当应用程序启动时,它会尝试调用 CreateFromFile( ) (我知道如果文件已经被某人映射 否则,这只会返回“句柄”),然后继续 对文件执行其工作。

问题是,当另一个进程已经这样做并且没有释放

The file is being used by another process
对象时,我在尝试 CreateFromFile( ) 时收到 IOException (
MemoryMappedFile
)。理论上,我可以使用互斥体并使用
using
语句不断地处理对象,但这会将内容转储到磁盘,再次减慢执行速度并达不到目的。

我的问题有哪些可能的解决方案?

理论上,我可以 CreateOrOpen( ) 一个非持久化文件,然后在需要时将其转储到磁盘,但我相信有更好的方法吗?

编辑:我觉得我没有说清楚。应用程序的所有实例都需要不断处理该文件,它们打开该文件并在接下来的 10、20、60 分钟内使用该文件,而无需关闭该文件。最终所有这些都将被杀死,这时操作系统就会介入,将映射文件刷新到磁盘。

示例程序:

方案A)

static void Main(string[] args)
    {
        var mmf = MemoryMappedFile.CreateFromFile(@"C:\Users\admin\Documents\Visual Studio 2010\Projects\serialize\serialize\bin\Debug\File.dat", FileMode.Open, "name");
        var accessor = mmf.CreateViewAccessor();
        accessor.Write(5, 'd');
        Console.Read();
    }

方案B)

static void Main(string[] args)

{
    var mmf = MemoryMappedFile.CreateFromFile(@"C:\Users\admin\Documents\Visual Studio 2010\Projects\serialize\serialize\bin\Debug\File.dat", FileMode.Open, "name");
    var accessor = mmf.CreateViewAccessor();
    accessor.Write(2, 'x');
    Console.Read();
}

我同时运行两者,让它们挂起等待

Console.Read()
。理想情况下,他们应该能够同时访问该文件(即,他们两个都可以在另一个文件打开后打开它),但如上所述,我收到了 IOException。

c# ipc memory-mapped-files
1个回答
0
投票

这就是 MMF 的要点。

如果您想使用已在使用的文件,则需要使用

OpenExisting
而不是
CreateFromFile
。您为每个 MMF 命名。在你的情况下,你选择了
"name"
。这就是你给予
OpenExisting
的东西。 https://learn.microsoft.com/en-us/dotnet/api/system.io.memorymappedfiles.memorymappedfile.openexisting?view=net-8.0#system-io-memorymappedfiles-memorymappedfile-openexisting(系统字符串)

这两个进程不仅打开同一个文件,而且还共享内存。因此,该名称让系统知道要共享什么。

由于您的程序是对称的,“第一个”程序应该使用

CreateFromFile
,“第二个”程序应该使用
OpenExisting
。您可以使用 try 块首先尝试创建然后存在,以便您可以使用相同的代码。

© www.soinside.com 2019 - 2024. All rights reserved.