两个进程(应用程序)之间共享内存

对于这个问题,我找不到任何有用的答案,虽然已经多次以不同的方式提出了这个问题。

我想在两个进程(两个不同的应用程序)之间共享内存,以便其中一个可以写入该内存,另一个可以读取。

这是可能的.NET? 怎么样?

谢谢

目前,.NET不支持部分(也称为内存映射文件)。 很快,4.0版本就有了System.IO.MemoryMappedFiles命名空间。 这是一个很好的理由花了这么长时间,也是你不会因为这个增加而感到高兴的原因。 在MMF中使用指针是强制性的,共享内存在特定地址可用。 要分享一个值,你必须把它写到一个特定的地址。

然而,指针从根本上与托pipe内存模型不兼容。 对象是在垃圾收集堆中创build的,收集器会根据需要移动它们以保持堆压缩。 在托pipe语言中,你有这样的一个对象的引用,也被称为“追踪句柄”。 C / C ++等价物是一个指针,但它是一个有声的,垃圾收集器总是可以找回它并更新它的值。 CLR确实支持“钉住”的概念,它将引用转换为指针。 它通过将对象标记为不可移动来实现这一点。 然而,这不会帮助通过MMF实现共享内存,该对象被固定在GC堆而不是MMF视图所在的虚拟内存地址。

为了使MMF工作,需要将对象从GC堆复制到共享内存。 这需要序列化。 .NET 4.0类被命名为MemoryMappedViewStream。 你可能会看到这是怎么回事,这与使用命名pipe道或套接字无法区分。 获取数据进出MMF需要花费相同的工作量。 MMF只是略微更有效,因为底层缓冲区不在内核内存池中。

你可以打破规则,今天就这样做。 你可以P / Invoke CreateFileMapping,OpenFileMapping和MapViewOfFile你需要创build一个MMF。 并使用不安全的关键字,所以你可以创build指针。 你需要为共享内存元素使用值types(比如struct)或者使用Marshal类。

IPC

如果你正在谈论进程间通信。 有几种可能性,例如使用tcp / udp套接字,邮槽,命名pipe道,内存映射文件,Windows消息等。

.Net也提供了一些更高层次的IPC,如.Net Remoting和WCF ,它们使用了前面提到的技术。 你可以在这里阅读更多。

内存映射文件

如果你真的想共享一块内存而不是通信,那么内存映射文件就是你想要的。 .Net 4.0有MemoryMappedFile的。 如果你没有或不能使用.Net 4.0,你可以自己实现,就像这个win32的例子 。 或者你可以尝试这个代码或看看你是否可以使用这里和这里提到的MemoryMappedFileStream。 或者使用这个FileMap类。

使用命名pipe道 。

这是一种机制,允许一个进程将顺序数据写入到一个stream中,另一个进程可以从中读取数据。

请注意,命名pipe道只允许顺序读取。 如果您需要使用更详细的查询,则可能需要使用客户端 – 服务器体系结构。 在这种情况下,读者进程使用networking套接字向另一个进程查询信息。

如前所述,使用内存映射文件。 .NET <4的实现可在: http : //github.com/tomasr/filemap/
我已经使用,它的工作完美无瑕。 在升级/未升级的进程之间共享时,可能会遇到一些安全问题 – 解决scheme是在升级的进程中初始化内存映射文件,并相应地设置其安全属性。