Linux进程通信之mmap

linux进程通信实现机制有很多,也有各自优缺点和适用场景,关于它们之间的对比,等各种通信机制一一介绍后,再来一个汇总,俗话说“没有对比就没有伤害”,通过“伤害”让大家彻底了解正确使用姿势 。
背景:原由一:对内存的管理 。大家熟悉的Glibc库提供的有:malloc、realloc、calloc(三者各自区别是什么,后续专题解说);
可能熟悉的有:google的Tcmalloc、FaceBook的Jemalloc,以及优化升级版的Ptmalloc;
brk、sbrk(用户和内核均可用来“申请内存”,这块后续专题介绍);

mmap,今天的主咖,一起看下她的前世今生,来龙去脉 。
Slab缓存机制、Buddy伙伴算法(这块后续专题介绍);
内核申请内存:kmalloc(内核空间,物理连续)、vmalloc(内核空间,物理不连续,虚拟连续 。思考malloc单次调用申请的内存在物理上连续不);
内核管理页表:pgd_offset(mm, addr)得到一级页表入口、pmd_offset(pgd, addr)得到二级页表入口
、通过pte_offset_map(pmd, addr)得到目标页表项;
get_zeroed_page(unsigned int flags);指向一个清零的新page、 __get_free_page(unsigned int flags);指向新页但不清零,实际上是用了order为0的下一个函数、__get_free_pages(unsigned int flags, unsigned int order);获取多个pages数量是2^order,不清零;
virt_to_phys()实现内核虚拟向物理地址的转化(感兴趣可以自行查看) 。
原由二:进程高效通信和文件读写【Linux进程通信之mmap】无名知道对于像有名/无名管道和消息队列等通信方式,需要在内核和用户空间进行两次运行级别切换(系统调用导致保护和恢复进程上下文环境)+四次数据拷贝,而共享内存则只拷贝两次数据: 一次从输入文件到共享内存区,另一次从共享内存区到输出文件 。实际上,进程之间在共享内存时,并不总是读写少量数据后就解除映射,有新的通信时,不用再重新建立共享内存区域,而是保持共享区域,直到通信完毕为止,这样,数据内容一直保存在共享内存中,并没有写回文件(内核通过一定策略刷盘,后续专题介绍) 。共享内存中的数据往往是在解除映射时才写回文件的 。因此,采用共享内存的通信方式效率是非常高的 。


    推荐阅读