专栏首页刘晓杰Linux和Android的IPC通信简介

Linux和Android的IPC通信简介

1.Linux和Android的IPC机制种类

IPC全名为inter-Process Communication,含义为进程间通信,是指两个进程之间进行数据交换的过程。在Android和Linux中都有各自的IPC机制,这里分别来介绍下。

1.1 Linux中的IPC机制种类

Linux中提供了很多进程间通信机制,主要有管道(pipe)、信号(sinal)、信号量(semophore)、消息队列(Message)、共享内存(Share Memory)、套接字(Socket)等。

1.2 Android中的IPC机制

Android系统是基于Linux内核的,在Linux内核基础上,又拓展出了一些IPC机制。Android系统除了支持套接字,还支持序列化、Messenger、AIDL、Bundle、文件共享、ContentProvider、Binder等。

2.Linux和Binder的IPC通信原理

在讲到Linux的进程通信原理之前,我们需要先了解Liunx中的几个概念。

概念

  • 内核空间和用户空间 User space(用户空间)和 Kernel space(内核空间)。内核空间是Linux内核的运行空间,用户空间是用户程序的运行空间。为了保护用户进程不能直接操作内核,保证内核的安全,操作系统从逻辑上将虚拟空间划分为用户空间和内核空间。Linux 操作系统将最高的1GB字节供内核使用,称为内核空间,较低的3GB 字节供各进程使用,称为用户空间。
  • 系统调用 用户空间需要访问内核空间,就需要借助系统调用来实现。系统调用是用户空间访问内核空间的唯一方式,保证了所有的资源访问都是在内核的控制下进行的,避免了用户程序对系统资源的越权访问,提升了系统安全性和稳定性。 进程A和进程B的用户空间可以通过如下系统函数和内核空间进行交互。 copy_from_user:将用户空间的数据拷贝到内核空间。 copy_to_user:将内核空间的数据拷贝到用户空间。
  • 内存映射 由于应用程序不能直接操作设备硬件地址,所以操作系统提供了一种机制:内存映射,把设备地址映射到进程虚拟内存区。 举个例子,如果用户空间需要读取磁盘的文件,如果不采用内存映射,那么就需要在内核空间建立一个页缓存,页缓存去拷贝磁盘上的文件,然后用户空间拷贝页缓存的文件,这就需要两次拷贝。由于新建了虚拟内存区域,那么磁盘文件和虚拟内存区域就可以直接映射,少了一次拷贝。 内存映射全名为Memory Map,在Linux中通过系统调用函数mmap来实现内存映射。将用户空间的一块内存区域映射到内核空间。映射关系建立后,用户对这块内存区域的修改可以直接反应到内核空间,反之亦然。内存映射能减少数据拷贝次数,实现用户空间和内核空间的高效互动。
2.1 Linux的IPC通信原理

Linux的IPC通信原理

内核程序在内核空间分配内存并开辟一块内核缓存区,发送进程通过copy_from_user函数将数据拷贝到到内核空间的缓冲区中。同样的,接收进程在接收数据时在自己的用户空间开辟一块内存缓存区,然后内核程序调用 copy_to_user() 函数将数据从内核缓存区拷贝到接收进程。这样数据发送进程和数据接收进程完成了一次数据传输,也就是一次进程间通信。 Linux的IPC通信原理有两个问题:

  • 一次数据传递需要经历:用户空间 --> 内核缓存区 --> 用户空间,需要2次数据拷贝,这样效率不高。
  • 接收数据的缓存区由数据接收进程提供,但是接收进程并不知道需要多大的空间来存放将要传递过来的数据,因此只能开辟尽可能大的内存空间或者先调用API接收消息头来获取消息体的大小,浪费了空间或者时间。
2.2 Binder的通信原理

Binder是基于内存映射来实现的,大致原理如下图:

Binder的通信原理

Binder通信的步骤如下

  • Binder驱动在内核空间创建一个数据接收缓存区。
  • 在内核空间开辟一块内核缓存区,建立内核缓存区和数据接收缓存区之间的映射关系,以及数据接收缓存区和接收进程用户空间地址的映射关系。
  • 发送方进程通过copy_from_user()函数将数据拷贝 到内核中的内核缓存区,由于内核缓存区和接收进程的用户空间存在内存映射,因此也就相当于把数据发送到了接收进程的用户空间,这样便完成了一次进程间的通信。 整个过程只使用了1次拷贝,不会因为不知道数据的大小而浪费空间或者时间,效率更高。

(PS:为啥需要两次映射?感觉一次就可以了)

3.Binder优势

  • 性能方面 性能方面主要影响的因素是拷贝次数,管道、消息队列、Socket的拷贝次书都是两次,性能不是很好,共享内存不需要拷贝,性能最好,Binder的拷贝次书为1次,性能仅次于内存拷贝。
  • 稳定性方面 Binder是基于C/S架构的,这个架构通常采用两层结构,在技术上已经很成熟了,稳定性是没有问题的。共享内存没有分层,难以控制,并发同步访问临界资源时,可能还会产生死锁。从稳定性的角度讲,Binder是优于共享内存的。
  • 安全方面 Android是一个开源的系统,并且拥有开放性的平台,市场上应用来源很广,因此安全性对于Android 平台而言极其重要。 传统的IPC接收方无法获得对方可靠的进程用户ID/进程ID(UID/PID),无法鉴别对方身份。Android 为每个安装好的APP分配了自己的UID,通过进程的UID来鉴别进程身份。另外,Android系统中的Server端会判断UID/PID是否满足访问权限,而对外只暴露Client端,加强了系统的安全性。
  • 语言方面 Linux是基于C语言,C语言是面向过程的,Android应用层和Java Framework是基于Java语言,Java语言是面向对象的。Binder本身符合面向对象的思想,因此作为Android的通信机制更合适不过。

从这四方面来看,Linux提供的大部分IPC机制根本无法和Binder相比较,而共享内存只在性能方面优于Binder,其他方面都劣于Binder,这些就是为什么Android要使用Binder来进行进程间通信,当然系统中并不是所有的进程通信都是采用了Binder,而是根据场景选择最合适的,比如Zygote进程与AMS通信使用的是Socket,Kill Process采用的是信号。

参考文章:https://www.jianshu.com/p/52e15875c81d

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • android注解

    包 java.lang.annotation 中包含所有定义自定义注解所需用到的原注解和接口。 如接口 java.lang.annotation.Annot...

    提莫队长
  • CountDownLatch介绍

    在项目中,我们通常会执行一些耗时操作,有的时候是同时执行若干个,然后执行完了还要等结果。通常我们会怎么做呢?Handler,或者runOnUIThread。但是...

    提莫队长
  • okhttp和责任链模式

    OkHttp—拦截器这篇文章讲了拦截器,今天就谈谈责任链模式 责任链模式,其实就是把request通过一系列Interceptor过滤,然后通过网络请求获取r...

    提莫队长
  • 极视角亮相腾讯全球数字生态大会,共筑智慧产业联合创新

    5月21日-23日,极视角科技携手腾讯云亮相首届「腾讯全球数字生态大会」,与包括英特尔、东华软件、日立集团等等一起,共同作为腾讯战略合作伙伴参展,联合打造数字化...

    深圳极视角
  • 把机器变成人!WeTest云测GDOC现场分享精选

    答应各位的GDOC现场分享终于整理成文了。特地精选了最重要、干货的部分呈现给大家。

    WeTest质量开放平台团队
  • 10分钟了解DevOps及常用工具集

    目前在国外,互联网巨头如Google、Facebook、Amazon、LinkedIn、Netflix、Airbnb,传统软件公司如Adobe、IBM、Micr...

    码农架构
  • 复制静止问题一则

    早上7点多接到一个数据库服务器空间报警,磁盘空间不足。登陆数据库查看,MySQL slave 大量延迟,有68G 的relay log。查看slave stat...

    用户1278550
  • .Neter所应该彻底了解的委托

    本文将通过引出几个问题来,并且通过例子来剖析C#中的委托以及用法,做抛砖引玉的作用

    ryzenWzd
  • Github 项目推荐 | 用 tf * idf 计算文本之间的相似度

    该库是具有 tf * idf 权重的 Ruby 向量空间模型(VSM),它能够用 tf * idf 计算文本之间的相似度。

    AI研习社
  • Pandas处理csv表格

    可以结合这篇使用:数据处理利器Pandas使用手册 1)读取csv文件 data =pandas.read_csv(‘test.csv’) //返回的是Data...

    MachineLP

扫码关注云+社区

领取腾讯云代金券