我的问题是,当我们创建匿名内存映射时,正在映射到进程地址空间中的文件是什么。我知道匿名映射一定会用零填充。然后是/ dev / zero文件吗?据我所知,进程间通信是不可能的,除非在参与进程的地址空间内映射了一些文件...无论是tmpfs还是普通文件系统中的文件。我是进程间通信的新手,如果您发现我的理解中有任何缺陷,请纠正。
来自man mmap
:
MAP_ANONYMOUS
映射没有任何文件支持; [...]
它只是分配并初始化内存。在调用mmap
之前,由于虚拟内存未映射到实际内存,因此您将在尝试访问内存时遇到保护冲突(SIGSEGV)。 (好吧,这就是带有虚拟内存的系统中发生的情况。)
我的问题是,当我们创建匿名内存映射时,正在映射到进程地址空间中的文件是什么。
没有文件。
我知道匿名映射一定会用零填充。那么是/ dev / zero文件吗?
编号
尽管,从历史上看,MAP_ANONYMOUS
标志是比mmap
本身更新的发明。在此之前,如果您想要一大块内存填充零并且没有任何常规文件支持,则确实可以打开/dev/zero
并映射它。这是操作系统的一种特殊情况,可以有效地为您提供匿名映射。创建/dev/zero
映射的不同进程即使使用MAP_SHARED
也不会看到彼此的数据。我相信MAP_ANONYMOUS
标志的引入是为了简化此过程,并避免了用于打开和关闭/dev/zero
的额外系统调用。
据我了解,只有在参与进程的地址空间中映射了一些文件之后,才能进行进程间通信……无论是tmpfs中的文件还是普通文件系统中的文件。
嗯,那不是真的; MAP_ANONYMOUS | MAP_SHARED
是一个例外。如果您的进程使用MAP_ANONYMOUS | MAP_SHARED
创建映射,则在此点之后使用fork()
创建的所有子代(及其子代,依此类推)也将具有该映射,并且内存将在所有它们和父代之间共享。这些进程中的任何进程对该内存的任何写操作都将被所有进程看到。
这的确意味着您只能将其用作“相关”进程之间的IPC,这是创建映射的共同祖先的后代(除非我不知道有巧妙的技巧可以访问不相关的进程)。映射实际文件(/dev/zero
除外)没有此限制。
当然,还有其他IPC机制根本不涉及文件,例如POSIX共享内存(shmget
和朋友)。