linux内核支持多种共享内存方式,如mmap内存映射,Posix共享内存,以system V共享内存。当内核空间和用户空间存在大量数据交互时,共享内存映射就成了这种情况下的不二选择。它能够最大限度的降低内核空间和用户空间之间的数据拷贝,从而大大提高系统的性能。
共享内存是最有用,也是最快的IPC方式。两个不同进程A、B共享内存时,同一块物理内存被映射到进程A、B各自的进程地址空间。进程A可以即时看到进程B对共享内存中数据的更新,反之亦然。由于多个进程共享同一块内存区域,必然需要某种同步机制,互斥锁和信号量都可以。
内存映射,简而言之就是将用户空间的一段内存区域(即进程地址空间的内存映射段,其位于堆空间和栈空间之间)映射到内核空间,映射成功后,用户对这段内存区域的修改可以直接反映到内核空间,同样,内核空间对这段区域的修改也直接反映用户空间,那么对于内核空间和用户空间两者之间需要大量数据传输等操作的话效率是非常高的。对于Posix共享内存和system V共享内存一样,在地址空间处于内存映射段,物理内存处于内核区。因此,这三种方式都不需要内核区与用户区进行数据的交换,效率更高,通过指针的方式可以直接对内存进行访问。对于大数据的内存访问,一般来说在Linux系统中采用内存映射和共享内存是最好的方式,这样对于应用层来说,可以很方便的访问到内核的空间。
mmap内存映射
mmap内存映射的方式分为两种:文件映射(一般文件或者/dev/zero文件)和匿名映射。文件映射,是指该地址空间(内存映射段)的内容来自于一个文件;而匿名映射地址空间背后什么靠山都没有。进程的代码段来自于镜像,采用文件映射方式;而栈,堆,.bss段,数据段均是匿名映射。
下图是文件映射的示意图(映射文件的一部分):