mmap是否与所有进程共享内存? [英] Does mmap share memory with all processes?

查看:86
本文介绍了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结构共享的确切共享内存?

When I mmap the pointer sharedPipe, if I invoke from main() any methods from myProgram code, would all processes share the exact shared memory that I shared with myPipe struct?

还是每个创建的新孩子都会拥有自己的新myPipe?

Or would each new child that's created, would have a new myPipe of his own?

致谢

这是在我阅读评论&答案:现在进行了更改,并且仅在分配段之后才初始化段的值:

This is after I read the comments & answers : now changes were made , and I initialize the values of the segment only after I allocate it :

#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
}

但是问题仍然存在,因为在运行和派生该main时,共享内存似乎并没有在进程之间共享:

The problem however continues ,the shared memory seems to be not so shared between the processes , since while running and forking that main :

int main()
{
    int spd, pid, rb;
    char buff[4096];

    fork();
    shm_pipe_init();

        // more
        return 0;
}

我仍然得到输出,该输出模拟仅运行一个进程的行为(而不是多个输出,我只能得到一个 one couple ,具体取决于进程之间的竞争条件).

I still get outputs , that simulates the behavior like only one process is running (instead of multiple outputs , I get only a single one or a couple ,depends on a race condition between the processes) .

推荐答案

如果您打算多次调用此程序,则答案为否".如果您打算在创建映射后进行派生,答案为是".

If you intend to call this program several times, the answer is "no". If you intend to fork after creating the mapping, the answer is "yes".

匿名映射没有基础文件.因此,创建匿名映射的过程无法特别指定它想要的现有映射(这也不是预期的用法,您应该获得一个新的,独立的映射).因此,第一种情况否".

An anonymous mapping has no underlying file. Therefore, a process creating an anonymous mapping has no way of specifying which already existing mapping in particular it wants (and this is also not the intended usage, you're supposed to get a new, independent one). Therefore "no" to the first case.

共享映射允许拥有相同映射的所有进程访问相同的物理内存.这意味着,如果您在创建映射后fork,则fork通常将以通常的方式工作,将进程拥有的所有页面标记为写时复制除外映射中的页面.父级和子级都将保留映射的页面,并且能够通过指针访问相同的物理内存(这意味着页面甚至也将具有相同的 virtual 地址-这通常,映射文件时您不能依靠它,但是在这种情况下,操作系统别无选择,只能确保确实如此.

A shared mapping allows all processes that own the same mapping to access the same phsyical memory. This means, if you fork after creating the mapping, then fork will mostly work the usual way, marking all pages owned by the process as copy-on-write except the pages in the mapping. Both the parent and the child will retain the mapped pages and will be able to access the same physical memory through the pointer (incidentially, this means the pages will even have the same virtual addresses, too -- this is normally not something you can rely on when mapping a file, but in this case the OS has no other choice but to make sure this is the case).

有关匿名映射和共享映射的组合或确切发生的内容,手册页仍然含糊不清,但是TLPI第49.7章明确提及了MAP_SHARED|MAP_ANONYMOUS:

The manpages remain vague about the combination of anonymous and shared mapping or about what exactly is supposed to happen, but TLPI chapter 49.7 explicitly mentions MAP_SHARED|MAP_ANONYMOUS:

[...],然后调用fork(),然后,因为fork()产生的子代继承了映射,所以两个进程共享内存区域.

[...] followed by a call to fork(), then, because the child produced by fork() inherits the mapping, both processes share the memory region.

因此,第二种情况为是".

Therefore "yes" for the second case.

回复:编辑过的帖子
错误的订单:

Re: edited post
Wrong order:

fork();
shm_pipe_init();

此操作先叉 ,然后初始化共享内存.映射 able ,将来可能会共享,如果该进程再次分叉,但不会神奇地与父级反向共享!) >分别针对每个进程.

This forks first and then initializes the shared memory. Which will just create a shared (read as share-able, it may be shared in the future, if the process forks again, but it does not magically back-share with the parent!) mapping for each process, separately.

然后,您有两个映射,每个进程一个,将由它们各自的子进程和孙进程(如果有)共享,但对实现您想要的目标没有任何帮助.它们是共享的"这一事实并不重要,它们是不同的映射,并且对于其他各个进程是未知的.

You then have two mappings, one in each process, which will be shared by their respective child and grandchild processes (if any), but which will help nothing to achieve what you want. The fact that they are "shared" does not matter, they're different mappings, and unknown to the respective other process.

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

First create the mapping, then fork. This will create one shared mapping that both processes indeed own/share and can use for the intended purpose.

(此外,您对fork的用法并不是严格错误,但是有点奇怪...通常应该检查返回值,因此您知道哪个是父级,哪个是子级.并不是fork不会失败,当然,如果那根本没关系,因为父母和孩子总是100%相同并且您不在乎失败,那很好,通常,一个人通常想知道,但.)

(Besides, your usage of fork is not strictly wrong, but a bit weird... you're normally supposed to check the return value, so you know which one is the parent and which one is the child. And it's not like fork can't fail. Of course if that doesn't matter at all because parent and child are always 100% identical and you don't care about failure, that's fine. Normally, one usually wants to know, though.)

这篇关于mmap是否与所有进程共享内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆