Linux 进程通信内存拷贝次数图解

一、进程通信中“拷贝”的概念

拷贝:

  • 广义上讲就是任何数据复制,但是在Linux系统中比较特殊,这里的概念比较狭义,物理内存之间的数据复制才叫拷贝
  • IO设备、Input 、DMA(Direct Memory Access)与其他设备之间的数据复制不能称为拷贝

为什么要着重强调这个概念呢?

因为很多博客中讲sendfile、mmap,多次拷贝的时候出现了描述矛盾的问题。

1、两次拷贝 (这张图上有3个物理内存)

  • Copy From User   用户态->内核态
  • Copy To User        内核态->用户态

因此传统IO上,进程间的通信经过两次拷贝,而且这只是单向传输数据,如果B进程要返回结果给A进程,只需要把这张图中的A进程和B进程角色关系调换一下。也是就是说,如果是带返回值的IPC,至少需要4次拷贝。

细品 Copy这个单词

我们发现,Copy From  User和Copy To User ? 作为主谓宾结构,到底是Who在Copy?

答案:是内核驱动程序,说明了一件事,进程通信需要内核允许

2、一次拷贝(这张图上有2个物理内存)

Binder 通信的实质,Binder 服务端和Binder用户端,进程A和B分别和内核态建立映射关系,这个映射关系依靠mmap完成,一次拷贝。

IPC通信,最多只需要2次拷贝,比传统方式少一倍。

3、0拷贝(这张图上1个物理内存)

A,B两用户态进程和内核态建立了同一虚拟内存地址的内存,因此,实现了内存共享,同样也是通过mmap实现

问题来了,共享内存这么高校为什么Android 通信不用?

实际上,Android并没有不用,只是在用户进程之间通信不推荐试用,Android使用共享内存的。Android使用共享内存的地方是SurfaceFlinger,Android App中可以使用共享内存的是工具是MemoryFile。

Google为什么不推荐呢?

共享内存无法实现高并发的复杂控制,可能出现用户进程A修改用户进程B数据的问题,对于一对一的通信缺陷并不大,但是多对一,多对多就是致命伤?

为什么SurfaceFlinger会使用共享内存?

  • SurfaceFlinger数据控制使用Binder,View绘制使用GraphicBuffer 共享内存
  • 共享内存传输数据非常高校,SurfaceFlinger直接和显示设备关联,需要尽可能避免图像数据延迟导致丢帧问题
  • 数据类型单一,无需安全校验
  • 进程之间是一对一,通过优先级合成图像

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值