当进程使用 shm_open() 时,Linux 内核如何分配内存指针?

发布于 2024-10-18 19:57:13 字数 837 浏览 4 评论 0原文

我使用的是 Linux 2.6,我遇到了一个奇怪的问题。我有 3 个并发进程(从同一进程派生),它们需要获取 3 个不同的共享内存段,每个进程一个。每个进程都执行此代码(请注意“消息”类型是用户定义的)

    message *m;
    int fd = shm_open("message", O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
    ftruncate(fd, sizeof(message));
    m = mmap(NULL, sizeof(message), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    char messagename[16];
    snprintf(messagename, sizeof(messagename), "%p", m);
    char path[32] = "/dev/shm/";
    strcat(path, messagename);
    rename("/dev/shm/message", path);

让我解释一下:我希望每个进程分配一个包含消息的共享内存区域。为了确保另一个进程(消息接收者)可以访问相同的 shm,然后我将 shm 文件从“message”重命名为以消息指针命名的字符串(这是因为接收消息的进程已经知道该指针)。

不过,在执行程序时,我尝试打印(出于调试目的)每个进程在映射使用 shm_open 获得的 fd 时收到的指针,并且我注意到它们都获得了相同的指针。怎么可能呢?我认为也许其他进程在第一个进程执行之后且在重命名该段之前执行了 shm_open() ,因此我还尝试通过使用进程共享互斥体使这些代码行成为原子操作,但问题仍然存在。

我真的很感激任何形式的帮助或建议。

I'm on Linux 2.6 and I have a weird problem. I have 3 concurrent processes (forked from the same process) which need to obtain 3 DIFFERENT shared memory segments, one for each process. Each of the process executes this code (please note that 'message' type is user-defined)

    message *m;
    int fd = shm_open("message", O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
    ftruncate(fd, sizeof(message));
    m = mmap(NULL, sizeof(message), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    char messagename[16];
    snprintf(messagename, sizeof(messagename), "%p", m);
    char path[32] = "/dev/shm/";
    strcat(path, messagename);
    rename("/dev/shm/message", path);

Let me explain a bit: I want every process to allocate a shared memory zone which contains a message. To make sure another process (the message receiver) can access the same shm, I then rename my shm file from "message" to a string named after the message pointer (this because the process which receives the message already knows the pointer).

When executing the program, though, I tried to print (for debugging purpose) the pointers that every process received when mmapping the fd obtained with shm_open, and I noticed that all of them got the SAME pointer. How is it possible? I thought that maybe other processes did the shm_open() after the first one did and before it renamed the segment, so I also tried to make these lines of code an atomic operation by using a process shared mutex, but the problem persists.

I would really appreciate any kind of help or suggestion.

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

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

发布评论

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

评论(3

青芜 2024-10-25 19:57:13

您的进程在分叉时都以相同的地址空间布局开始,然后遵循非常相似的代码路径。因此,它们最终都具有相同的 m 值也就不足为奇了。

然而,一旦它们成为单独的进程,它们的地址空间就变得独立,因此具有相同的 m 并不意味着所有的 m s 都指向同一件事。

此外,我不确定您在创建共享内存块后重命名 /dev/shm 条目的想法是否安全或可移植。如果你希望每个进程的共享内存块都有一个唯一的名称,为什么不将名称基于进程ID(保证在给定时间点是唯一的)并将其直接传递给shm_open,而不是去麻烦之后重命名吗?

Your processes all started with identical address space layouts at the moment of forking, and then followed very similar code paths. It is therefore not surprising that they all end up with the same value of m.

However, once they became separate processes, their address spaces became independent, so having the same value of m does not imply that all of the ms are pointing to the same thing.

Furthermore, I am not sure that your idea of renaming the /dev/shm entry after creating the shared memory block is safe or portable. If you want each process's shared memory block to have a unique name, why not base the name on the process ID (which is guaranteed to be unique at a given point in time) and pass it directly to shm_open, rather than going to the bother of renaming it afterwards?

百思不得你姐 2024-10-25 19:57:13

不同进程中的相同虚拟地址可以(并且通常确实)映射到内存中的不同物理页。您可能想阅读有关虚拟内存的维基百科文章

The same virtual address in different processes can (and usually does) map to different physical pages in memory. You might want to read the wikipedia article on virtual memory.

衣神在巴黎 2024-10-25 19:57:13

我通过在分叉之前创建 mmap 解决了类似的问题。因此,分叉后,所有进程之间共享同一区域。然后,我将信号量和互斥体放在定义的位置上。它工作完美。

I solved a similar problem simply by making the mmap before forking. So after forking the same area is shared between all processes. I then put my semaphores and mutexes on defined positions. It works perfectly.

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