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

发布于 2024-08-16 16:20:25 字数 132 浏览 9 评论 0原文

尽管已经以不同的方式多次询问过这个问题,但我找不到任何有用的答案。

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

这在.NET 中可能吗?如何?

谢谢

I can't find any useful answer for this question, although it has been asked in a different way several times.

I want to share a memory between two processes (two different applications),
so that one of them can write to that memory and the other can read.

Is this possible in .NET? How?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

榕城若虚 2024-08-23 16:20:25

目前,.NET 不支持段(也称为内存映射文件)。很快,4.0版本就有了System.IO.MemoryMappedFiles命名空间。花了这么长时间是有充分理由的,也是您对这一添加不满意的原因。在 MMF 中必须使用指针,共享内存在特定地址处可用。要共享值,您必须将其写入特定地址。

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

为了使 MMF 工作,需要将对象从 GC 堆复制到共享内存。这就需要序列化。 .NET 4.0 类名为 MemoryMappedViewStream。您可能可以看到这是怎么回事,这与使用命名管道或套接字没有什么区别。将数据传入和传出 MMF 需要花费相同的精力。 MMF 只是效率稍高一些,因为底层缓冲区不在内核内存池中。

你可以打破规则,今天就这样做。您可以 P/Invoke 创建 MMF 所需的 CreateFileMapping、OpenFileMapping 和 MapViewOfFile。并使用 unsafe 关键字,以便您可以创建指针。您需要对共享内存元素使用值类型(如结构)或使用 Marshal 类。

Right now, .NET doesn't support sections (aka Memory Mapped Files). It will soon, the 4.0 version has the System.IO.MemoryMappedFiles namespace. There is a good reason it took so long and also the reason you are not going to be happy with this addition. Using pointers is mandatory in MMFs, the shared memory is made available at a specific address. To share a value, you'll have to write it to a specific address.

Pointers are however fundamentally incompatible with the managed memory model. Objects are created in a garbage collected heap, the collector moves them around as needed to keep the heap compacted. In a managed language, you have a reference to such an object, also knows as a "tracking handle". The C/C++ equivalent is a pointer, but it is one with bells on, the garbage collector can always find it back and update its value. The CLR does support the notion of "pinning", it converts a reference to a pointer. It implements this by marking the object as unmoveable. That however doesn't help implement shared memory through an MMF, the object is pinned in the GC heap instead of the virtual memory address where the MMF view is located.

To make an MMF work, the object needs to be copied from the GC heap to the shared memory. That requires serialization. The .NET 4.0 class is named MemoryMappedViewStream. You probably can see where this is going, this is indistinguishable from using a named pipe or a socket. Getting data in and out of an MMF takes the same amount of effort. An MMF is merely slightly more efficient because the underlying buffer is not in the kernel memory pool.

You can break the rulez and do so today. You can P/Invoke the CreateFileMapping, OpenFileMapping and MapViewOfFile you need to create an MMF. And use the unsafe keyword so you can create pointers. You'll need to use value types (like struct) for the shared memory elements or use the Marshal class.

影子是时光的心 2024-08-23 16:20:25

IPC

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

还提供了一些更高级别的 IPC,例如 .Net 远程处理WCF 使用前面提到的技术。您可以在此处阅读更多相关信息。

内存映射文件

如果您确实想共享一块内存而不是通信,那么内存映射文件可能就是您想要的。 .Net 4.0 有 MemoryMappedFile 为此。如果您不或不能使用 .Net 4.0,您可以自己实现它,如下 win32 示例。或者您可以尝试 代码或查看是否可以使用提到的 MemoryMappedFileStream 此处此处。或者使用这个 FileMap 类。

IPC

If you are talking about Inter Process Communication. There are several possibilities like using tcp/udp sockets, mailslots, named pipes, memory mapped files, windows messages, etc.

.Net also offers some higher level IPC like .Net remoting and WCF which use the previous mentioned techniques. You can read more about it here.

Memory Mapped Files

If you really want to share a block of memory instead of communication then maybe memory mapped files are what you want. .Net 4.0 has MemoryMappedFile for that. If you don't or can't use .Net 4.0 you could implement it yourself as in this win32 example. Or you could try this code or see if you can use MemoryMappedFileStream mentioned here and here. Or use this FileMap class.

梦途 2024-08-23 16:20:25

使用命名管道

它是一种允许一个进程将顺序数据写入流中的机制,其他进程可以从中读取数据。

请注意,命名管道仅允许顺序读取。如果您需要使用更详细的查询,您可能需要使用客户端-服务器架构。在这种情况下,读取器进程使用

Use a named pipe.

It's a mechanism that allows one process to write sequential data into a stream, from which the other process can read.

Note that named pipe only allow sequential read. If you need to use more elaborated queries, you might want to use client-server architecture. In this case, the reader process queries the other process for information using network sockets.

苄①跕圉湢 2024-08-23 16:20:25

正如已经提到的,使用内存映射文件。
.NET 的实现4 位于:http://github.com/tomasr/filemap/
我已经使用过并且效果完美。在提升/未提升的进程之间共享时,您可能会遇到一些安全问题 - 解决方案是在提升的进程中初始化内存映射文件并相应地设置其安全属性。

As already mentioned use Memory Mapped Files.
Implementation for .NET < 4 available at: http://github.com/tomasr/filemap/
I have used and it works flawless. You may have some security issues when sharing between elevated/not elevated processes - the solution is to initialize the memory mapped file in the elevated process and set its security attributes accordingly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文