简介
linux中的两种共享内存。一种是我们的IPC通信System V版本的共享内存,另外的一种是存储映射I/O(mmap函数)
在说mmap之前我们先说一下普通的读写文件的原理,进程调用read或是write后会陷入内核,因为这两个函数都是系统调用,进入系统调用后,内核开始读写文件,假设内核在读取文件,内核首先把文件读入自己的内核空间,读完之后进程在内核回归用户态,内核把读入内核内存的数据再copy进入进程的用户态内存空间。实际上我们同一份文件内容相当于读了两次,先读入内核空间,再从内核空间读入用户空间。
Linux提供了内存映射函数mmap, 它把文件内容映射到一段内存上(准确说是虚拟内存上),通过对这段内存的读取和修改, 实现对文件的读取和修改,mmap()系统调用使得进程之间可以通过映射一个普通的文件实现共享内存。普通文件映射到进程地址空间后,进程可以向访问内存的方式对文件进行访问,不需要其他系统调用(read,write)去操作。
共享内存-System V
|
|
内存布局
mmap
####a. /dev/zero####
设备/dev/zero在读时,是0字节的无限资源。此设备也接收写向它的任何数据,但忽略此
数据。我们对此设备作为IPC的兴趣在于,当对其进行存储映射时,它具有一些特殊性质:
• 创建一个未名存储区,其长度是mmap的第二个参数,将其取整为系统上的最近页长。
• 存储区都初始化为 0。
• 如果多个进程的共同祖先进程对mmap指定了MAP_SHARED标志,则这些进程可共享此存储区。
使用/dev/zero的优点是:在调用mmap创建映射区之前,无需存在一个实际文件。映射/dev/zero自动创建一个指定长度的映射区。
这种技术的缺点是:它只能由相关进程使用。如果在无关进程之间需要使用共享存储区,则必须使用shmXXX函数。
example
####b.匿名存储映射
4.3+BSD提供了一种类似于/dev/zero的施设,称为匿名存储映射。为了使用这种功能,在调用mmap时指定MAP_ A NON标志,并将描述符指定为-1。
example