共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据(如图)。

共享内存 VS. 其他IPC形式
用管道/消息队列传递数据
用共享内存传递数据
共享内存生成之后,传递数据并不需要再走Linux内核,共享内存允许两个或多个进程共享一个给定的存储区域,数据并不需要在多个进程之间进行复制,因此,共享内存的传输速度更快!
将文件/设备空间映射到共享内存区
参数:
addr: 要映射的起始地址, 通常指定为NULL, 让内核自动选择;
length: 映射到进程地址空间的字节数;
prot: 映射区保护方式(见下);
flags: 标志(见下);
fd: 文件描述符;
offset: 从文件头开始的偏移量;
prot
说明
PROT_READ
页面可读
PROT_WRITE
页面可写
PROC_EXEC
页面可执行
PROC_NONE
页面不可访问
flags
MAP_SHARED
变动是共享的
MAP_PRIVATE
变动是私有的
MAP_FIXED
准确解释addr参数, 如果不指定该参数, 则会以4K大小的内存进行对齐
MAP_ANONYMOUS
建立匿名映射区, 不涉及文件
mmap返回值:
成功: 返回映射到的内存区的起始地址;
失败: 返回MAP_FAILED;
内存映射示意图:
(注意: 内存映射时, 是以页面(4K)作为单位)
map注意点:
1. 内存映射不能(也不可能)改变文件的大小;
2. 可用于进程间通信的有效地址空间不完全受限于映射文件的大小, 而应该以内存页面的大小为准(见下面测试);
3. 文件一旦被映射之后, 所有对映射区域的访问实际上是对内存区域的访问; 映射区域内容写会文件时, 所写内容不能超过文件的大小.
msync函数
对映射的共享内存执行同步操作
addr: 内存起始地址;
length: 长度
flags: 选项
MS_ASYNC
执行异步写
MS_SYNC
执行同步写, 直到内核将数据真正写入磁盘之后才返回
MS_INVALIDATE
使高速缓存的数据失效
返回值:
成功: 返回0;
失败: 返回-1;