Linux 通过使用 mmap() 在进程之间共享内存

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4991533/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 02:51:37  来源:igfitidea点击:

Sharing memory between processes through the use of mmap()

clinuxipcshared-memorymmap

提问by Andrea Sprega

I'm in Linux 2.6. I have an environment where 2 processes simulate (using shared memory) the exchange of data through a simple implementation of the message passing mode.

我在 Linux 2.6 中。我有一个环境,其中 2 个进程通过消息传递模式的简单实现来模拟(使用共享内存)数据交换。

I have a client process (forked from the parent, which is the server) which writes a struct(message) to a memory mapped region created (after the fork) with:

我有一个客户端进程(从父进程分叉出来,即服务器),它将一个结构(消息)写入创建(在分叉之后)的内存映射区域:

message *m = mmap(NULL, sizeof(message), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0)

message *m = mmap(NULL, sizeof(message), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0)

This pointer is then written to a queue (in form of a linked list) into another shared memory area which is common to server and client process (because if was created prior to fork with the same code above). This area is then read by the server which obtains the pointer to the message and processes it.

然后将此指针写入队列(以链表的形式)到服务器和客户端进程共有的另一个共享内存区域(因为 if 是在使用上述相同代码的 fork 之前创建的)。该区域然后由服务器读取,服务器获得指向消息的指针并对其进行处理。

The problem is that *m is created after the fork() and when the server process tries to access the pointed memory location, i get a segmentation error. Is it possible to attach that region of memory to the server POST forking, after the client creates it?

问题是 *m 是在 fork() 之后创建的,当服务器进程尝试访问指向的内存位置时,出现分段错误。在客户端创建它之后,是否可以将该内存区域附加到服务器 POST 分叉?

NOTE: I don't want to mmap the pointer to message before forking (and then sharing it prior with the server) because I typically don't know how many messages the client wants to send to the server, and also there may be more than 1 client process, so I'd like to create a new block of shared memory only when a client needs to send a message, and unmap it after the server has received that message.

注意:我不想在分叉之前将指针映射到消息(然后与服务器共享它),因为我通常不知道客户端想要发送多少消息到服务器,而且可能还有更多比 1 个客户端进程,所以我想仅在客户端需要发送消息时创建一个新的共享内存块,并在服务器收到该消息后取消映射。

NOTE: This is for academic purpose: I know this is not the best way to solve this problem, but I just need to follow this path.

注意:这是出于学术目的:我知道这不是解决此问题的最佳方法,但我只需要遵循此路径即可。

Thanks in advance!

提前致谢!

采纳答案by Maxim Egorushkin

Is it possible to attach that region of memory to the server POST forking, after the client creates it?

在客户端创建它之后,是否可以将该内存区域附加到服务器 POST 分叉?

MAP_ANONYMOUS|MAP_SHAREDmapped memory can only be accessed by the process which does that mmap()call or its child processes. There is no way for another process to map the same memory because that memory can not be referred to from elsewhere since it is anonymous.

MAP_ANONYMOUS|MAP_SHARED映射内存只能由执行该mmap()调用的进程或其子进程访问。另一个进程无法映射相同的内存,因为该内存无法从其他地方引用,因为它是匿名的

Using shm_open()call it is possible to create namedshared memory which can be referred to and mapped by unrelated processes.

使用shm_open()call 可以创建命名共享内存,它可以被无关进程引用和映射。

回答by MarkR

That's not going to work.

那是行不通的。

If you create a mapping after the fork(), it won't be the same in the other related process(es).

如果在 fork() 之后创建映射,则其他相关进程中的映射将不同。

You can't assume the sharing of pointers in this way.

您不能假设以这种方式共享指针。

If you really want to do it this way (I would not recommend it!), you should mmap a big area before the fork(), then allocate somehow, buffers of a suitable size (without race conditions with other processes, of course!) and pass those pointers.

如果你真的想这样做(我不推荐它!),你应该在 fork() 之前映射一个大区域,然后以某种方式分配合适大小的缓冲区(当然没有与其他进程的竞争条件! ) 并传递这些指针。

Two related processes which call mmap() after a fork, may get the same pointer back, pointing at different memory. In fact this is extremely likely.

在 fork 之后调用 mmap() 的两个相关进程可能会返回相同的指针,指向不同的内存。事实上,这是极有可能的。

回答by Lothar

Just for anyone reading this question in 2018 and later. The solution is now to use memfd_create to create an anonymous file and use a unix socket to pass this file handle to the other process.

仅适用于在 2018 年及以后阅读此问题的任何人。现在的解决方案是使用 memfd_create 创建一个匿名文件,并使用 unix socket 将这个文件句柄传递给另一个进程。

memfd_create is a linux only syscall

memfd_create 是一个仅限 Linux 的系统调用