共享内存区是最快的IPC形式,一旦这样的内存区映射到共享它的进程的地址空间,这些进程的数据传递就不再涉及内核。
Mmap函数把一个文件或一个Posix共享内存区对象映射到调用进程的地址空间。使用该函数有三个目的: 使用普通文件提供内存映射 使用特殊文件提供匿名内存映射 使用shm:open提供无亲缘关系进程间的Posix共享内存区
#include<sys/mman.h>
Void *mmap(void *addr, size_t len, int prot, int flag, int fd, off_t offset);
返回:成功时为被映射区的起始地址,出错时为MAP_FAILED
Addr可以指定描述字fd应被映射到的进程内空间的起始地址,通常为空,表示告诉内核自己去选择起始地址 Len是映射到进程地址空间的字节数,它从被映射文件的开头起offset字节处开始算。Offset通常为0
内存映射区的保护由prot参数指定,它使用图12.7中的常值。该参数的常见值是代表读写访问的PROT_READ|PORT_WRITE
Flags使用图12.8中的常值指定。MAP_SHARED或MAP_PRIVATE这两个标识必须指定一个,并可有选择的或上MAP_FIXED
可移植的代码应把addr=NULL,并且不指定MAP_FIXED
为从某个进程的地址空间删除一个映射关系,我们调用munmap
#include<sys/mmap.h>
Int munmap(void *addr, size_t len);
返回:成功时为0,出错时为-1
可以通过调用msync()函数来实现磁盘文件内容与共享内存区中的内容一致,即同步操作.
#include<sys/mman.h>
int msync ( void * addr, size_t len, int flags)
flags:刷新的参数设置,可以取值MS_ASYNC/ MS_SYNC/ MS_INVALIDATE 取值为MS_ASYNC(异步)时,调用会立即返回,不等到更新的完成; 取值为MS_SYNC(同步)时,调用会等到更新完成之后返回; 取MS_INVALIDATE(通知使用该共享区域的进程,数据已经改变)时,在共享内容更改之后,使得文件的其他映射失效,从而使得共享该文件的其他进程去重新获取最新值; MS_ASYNC和MS_SYNC只能二选一
4.4BSD提供匿名内存映射,它彻底避免了文件的创建和打开。其办法是把mmap的flags参数指定成MAP_SHARED|MAP_ANON,把参数fd指定为-1.offset参数被忽略。这样的内存区初始化为0. SVR4提供/dev/zero设备文件,我们在open它之后可在mmap调用中使用得到描述字。