如何在fork或子进程之后创建共享内存?

时间:2017-10-15 03:01:43

标签: c linux

如何在fork或子进程之后创建共享内存?

我想首先在共享内存中创建一个全局指针,然后在子进程中动态创建多个节点并将该节点添加到此全局指针。

#include <string.h>
#include <unistd.h>

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>

struct shm_t {
        int data;
        struct shm_t *next;
};

void main() {
        struct shm_t *shm = (struct shm_t *)mmap(NULL, sizeof(*shm), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, 0, 0);

        shm->data = 1;
        shm->next = NULL;

        int pid = fork();

        if (pid == 0) {
                printf("Child \n");
                // How to create a shared shm_t here, and assign to *shm->next?
        } else {
                printf("Parent \n");
        }
}

1 个答案:

答案 0 :(得分:1)

为了让两个进程共享内存,他们必须有一些共同点。

您的第一个分配是共享的,因为您使用MAP_SHARED分配了它,并且子进程从父级继承了它。一旦fork已经完成,就没有办法自动完成(只有一个例子:子进程与哪个进程共享?父进程只是一个没有特殊意义的随机进程,就Linux而言)。

正确执行此操作的方法是共享文件描述符。然而,这里的陷阱数量是惊人的。

让我们先从解决方案开始,然后了解它为什么不能解决问题:

// Before the fork
int shared_fd = open("/dev/shm/somefile", O_CREAT|O_TRUNC|O_EXCL|O_RDWR, 0600);
// Check for errors
unlink("/dev/shm/somefile");
// check for errors

// Now you can fork

如果您现在使用此文件中的mmap,则可以在进程之间共享它(即 - 一个进程&#39;写入将对其他进程可见)。

正如我所说,这里的陷阱数量巨大:

  • 文件是空的,您不能mmap超过文件的末尾。为此,您需要使用ftruncate增加文件。但这是一个问题。对ftruncate的调用需要同步,否则您将遇到丢失的更新问题,其中两个进程都认为它们将文件一起增加到相同的大小。
  • 即使你这样做了,你仍然无法在内存中存储指针。原因是内存是共享的,在某种意义上说,一个进程是写入立即对另一方可见。但是,无法保证它们将映射到相同的地址。

我不确定你想在这里做什么(如果你想在两个进程之间共享一个链表,那么你也需要处理很大的同步问题)。如果您可以对您需要的内存量提供先验限制,请使用原始mmap预分配。

但是,很有可能,你在这里尝试实现的目标是不可能实现的(不是以任何理智的方式)。