Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何在fork之后或子进程中创建共享内存?_C_Linux - Fatal编程技术网

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

C 如何在fork之后或子进程中创建共享内存?,c,linux,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

如何在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");
        }
}
#包括
#包括
#包括
#包括
#包括
结构shm\t{
int数据;
结构shm_t*下一步;
};
void main(){
结构shm_t*shm=(结构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();
如果(pid==0){
printf(“Child\n”);
//如何在此处创建共享shm,并分配给*shm->next?
}否则{
printf(“父项”);
}
}

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

您的第一次分配是共享的,因为您使用
MAP\u 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
,则可以在进程之间共享它(即,一个进程的写入将对另一个进程可见)

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

  • 创建的文件为空,并且您不能
    mmap
    超过文件的结尾。为了使其工作,您需要使用
    ftruncate
    增加文件。不过,这里有一个问题。对
    ftruncate
    的调用需要同步,否则会出现更新丢失的问题,这两个进程都认为它们正在将文件增加到相同的大小
  • 即使这样做了,仍然无法在内存中存储指针。原因是内存是共享的,即一个进程的写操作对另一个进程是立即可见的。但是,不能保证它们将映射到相同的地址
我不确定您想在这里做什么(如果您想在两个进程之间共享一个链表,那么这里也需要处理大量的同步问题)。如果您可以提供所需内存的先验限制,只需使用原始
mmap
预先分配内存即可


然而,很有可能,您在这里试图实现的目标是不可能以您试图实现的方式实现的(不是以任何理智的方式)。

在如此小的内存块中分配共享内存是非常低效的,会导致您很快用完。您最好分配一个超出您需要的数量,并实现您自己的分配器/deallocator(使用
MADV_DONTNEED
释放)。@Ignacio有可能实现吗?@o11c数量不同,有时可能是1mb,有时可能是10gb,如果我在开始时分配10gb,操作系统实际上分配了10吗?@vego没有,它只保留虚拟地址空间。在您实际访问它之前,不会涉及任何物理页面。