mmap是否与所有进程共享内存?

当我这样做:

myProgram.h myProgram.c struct PipeShm { // all my fields // more // ... }; struct PipeShm myPipe = { /* initialization for all fields */ }; struct PipeShm * sharedPipe = &myPipe; void func() { sharedPipe = mmap (NULL, sizeof * sharedPipe, PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS, -1, 0); } 

当我mmap指针sharedPipe ,如果我从main()myProgram代码调用任何方法,所有进程将共享共享与myPipe结构共享的内存?

或者每个新创build的孩子都会拥有一个新的myPipe

问候

编辑:

这是我读了评论和答案后:现在已经做了改变,我只是在分配它之后初始化段的值:

 #include "my_pipe.h" struct PipeShm * sharedPipe = NULL; int shm_pipe_init() { if (!sharedPipe) { int myFd = shm_open ("/myregion", O_CREAT | O_TRUNC | O_RDWR, 0600); if (myFd == -1) error_out ("shm_open"); // Allocate some memory in the region - We use ftruncate, write(2) would work just as well int retAlloc = ftruncate (myFd, sizeof * sharedPipe); if (retAlloc < 0) error_out("ftruncate"); sharedPipe = mmap (NULL, sizeof * sharedPipe, PROT_READ | PROT_WRITE,MAP_SHARED | MAP_ANONYMOUS, myFd, 0); if (!sem_init (&sharedPipe->semaphore, 1, 0)) { sharedPipe->init = TRUE; sharedPipe->flag = FALSE; sharedPipe->ptr1 = NULL; sharedPipe->ptr2 = NULL; sharedPipe->status1 = -10; sharedPipe->status2 = -10; sharedPipe->semaphoreFlag = FALSE; sharedPipe->currentPipeIndex = 0; } else perror ("shm_pipe_init"); } return 1; // always successful } 

然而,问题仍然存在,共享内存似乎不是在进程之间共享的,因为在运行和分配主进程时:

 int main() { int spd, pid, rb; char buff[4096]; fork(); shm_pipe_init(); // more return 0; } 

我仍然得到输出,模拟像只有一个进程正在运行的行为(而不是多个输出,我只得到一个或一 ,取决于进程之间的竞争条件)。

Solutions Collecting From Web of "mmap是否与所有进程共享内存?"

如果您打算多次致电该计划,答案是“否”。 如果你打算在创建映射后分叉,答案是“是”。

匿名映射没有底层文件。 因此,创建匿名映射的进程没有办法指定特定的映射(这也不是预期的用法,你应该得到一个新的,独立的映射)。 因此,对第一种情况“不”。

共享映射允许拥有相同映射的所有进程访问相同的物理内存。 这意味着,如果在创建映射之后进行fork ,那么fork将主要以通常的方式工作,将进程拥有的所有页面标记为写入时的页面之外的所有页面。 父母和孩子都将保留映射的页面,并能够通过指针访问相同的物理内存(这意味着页面甚至会拥有相同的虚拟地址 – 通常情况下,这不是您可以依赖的在映射文件时,在这种情况下,操作系统没有别的选择,只能确保是这种情况)。

关于匿名映射和共享映射的组合,或者关于究竟应该发生什么,联机帮助页仍然是模糊的,但TLPI第49.7章明确提到了MAP_SHARED|MAP_ANONYMOUS

然后,调用fork(),然后,由于由fork()生成的子继承映射,两个进程共享内存区域。

因此,对于第二种情况,“是”。

回复:编辑后
错误的顺序:

 fork(); shm_pipe_init(); 

首先分叉,然后初始化共享内存。 对于每个进程 ,这将只是创建一个共享(如果进程分叉,可能会共享,将来会共享,但不会与父进程分享)映射。

然后,您有两个映射,每个流程都有一个映射,这些映射将由各自的子孙进程(如果有的话)共享,但是无法实现您想要的。 它们“共享”的事实并不重要,它们是不同的映射,对于其他过程是未知的。

首先创建映射, 然后 fork。 这将创建一个共享的映射,这两个进程确实拥有/共享,并可以用于预期的目的。

(另外,你对fork的使用并不是严格的错误,但有点怪异的…你通常应该检查返回值,所以你知道哪个是父类,哪个是孩子,而且不是fork当然,如果那根本没有关系,因为父母和孩子总是100%相同,你不关心失败,那很好,通常情况下,人们通常会想知道)。

每个都有自己的,因为对指针 sharedPipe更改不会影响myPipe

让我们逐步了解你在这里做的事情

 struct PipeShm myPipe = { /* initialization for all fields */ }; 

这将PipeShm结构分配为全局变量

 struct PipeShm * sharedPipe = &myPipe; 

这将创建一个指向先前创建的结构的指针

现在你正在修改指针sharedPipe到什么mmap返回(大概是一个共享内存区域的地址),而不是你之前分配的结构(注意: myPipe仍然存在 – 只是没有指向)。

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

据我所知,你也没有尝试访问sharedPipe 。 所以现在,你基本上有一个全局变量一段共享内存(这两个都是未使用的)。

这是我不太确定你在做什么。

如果你想访问共享内存,你需要在mmap返回后取消引用sharedPipe指针(如果是的话,全局变量的意义是什么?)。

如果你想访问全局变量,只需将它作为myPipe来访问(如果是这样,那么mmap是什么?)。

如果你想访问这两者,那么使用上述的组合(如果是的话,做什么是struct PipeShm * sharedPipe = &myPipe;