[083]Binder答疑解惑(一)

2023-09-09 16:00:55 浏览数 (1)

问题

为什么已经有了管道等跨进程通信方式,却要另外创建Binder方式?直接在原来的跨进程方式上面修改,不是更加方便吗?

一、跨进程通信共性

跨进程通信就是两个进程之前的数据传递。

如何才能跨进程通信?

我能想到最简单的跨进程通信就是在sdcard目录下创建一个文件1.txt,然后应用A写数据,应用B读数据。

这里抽象出,任何跨进程通信绕不开的两个关键的共性问题:

1.找到一片两个进程都可以访问数据存放区域

例子一中数据存放区域就是磁盘

2.让两个进程在事先无法通信的情况下,按照某种约定对这个数据存放区域进行读写

例子二中约定就是应用A写sdcard/1.txt,应用B读sdcard/1.txt

二、匿名管道(pipe)

共性问题1:

进程间的内核共享内存区域

共性问题2:

由于匿名管道只能通过父进程fork子进程的时候让两个进程分别持有pipe的两端fd,然后分别读写fd进行通信,所以匿名管道不适合跨进程通信,无法通过约定让两个没有关系的进程进行跨进程通信

三、实名管道(fifo)

实名管道解决了共性问题2,如何进行简单的约定,这个约定就是约定pathname,然后分别读写。

例如应用A和应用B约定实名的管道分别是./A_B和./B_A,这样子就可以让应用A和B分别读写了。

四、Socket通信

localsocket也是约定类似的pathname,然后通过socket的文件的读写进行通信。
网络socket通信就是约定了ip地址,双方需要实现约定某个ip地址或者端口。

约定某个ip地址,例如访问某个网站,就是约定dns服务器,然后访问dns服务器ip,传递网址返回要请求的ip,获得实际要访问的ip,在进行ip的访问,当然还有对应的tcp/ip的协议栈了,这些都是约定。

约定某个端口,就是类似someip的协议,约定双方要监听的端口是30490,然后具体的约定就是someip的协议和网络协议栈。

可以参考我之前的文章 https://cloud.tencent.com/developer/article/2290363

怎么有点奇怪的感觉

好像已经有人干了在原来的跨进程方式上面修改,然后形成跨进程通信的方案了。那就是someip,基于socket通信开发的。

五、只有Binder能做到的事

5.1 一次拷贝-性能

前面所有讲的跨进程通信方式都是两次拷贝,需要从用户态到内核态,内核态到用户态两次数据拷贝。只有重新写驱动才能实现一次拷贝。

5.2 fd的传递

fd的传递不是简单的fd数字的传递,而是新的fd对应file结构体在对端关联。会有人说,那传递fd对应的文件路径,重新打开不就行了,但是此fd是linux中一切皆文件的概念,很多fd并不一定会有文件路径对应。现有的跨进程通信无法做到。而且重新打开文件路径,会创建一个新的file内核结构体,读写指针无法共享。

参考我之前的文章 https://cloud.tencent.com/developer/article/1639804

5.3 远程转本地

如果发现最后被请求的进程和发起请求的进程是同一个进程,如何高效的通信犹如函数调用一样。

参考我之前的文章 https://cloud.tencent.com/developer/article/1639790

5.4 线程栈复用

如果发现A请求B,B请求C,C又请求A,如何利用A请求B时候休眠的线程进行C的响应,减少线程资源的浪费。

参考我之前的文章 https://cloud.tencent.com/developer/article/1639787

小结

以上的几个功能都很难利用现有的跨进程通信的方式,二次开发实现,因为二次开发只能在用户态了。为什么Binder要实现上述这几个功能,我猜是因为刚开始的时候移动端性能差,内存紧张,对现有跨进程通信的性能要求高,以及大规模进程之间通信管理难度加大要求,从而萌生了重新从驱动开始写一套跨进程通信机制的想法,当然不是从零开始思考的,我认为作者在用户态的通信协议,有点参考了JavaRMI思想,因为javaRMI是在1998年发布的,Binder应该比它晚,后面2011年发布的someip我猜也或多或少借鉴了JavaRMI的思考。

六、Binder的缺点

Binder那么好用也没有用在车上?

因为Binder暂不支持跨芯片通信,汽车上更多的是跨设备通信和跨进程通信混合,有可能某个需求一变,原本只需要跨进程通信要变成跨芯片通信了,这样子代码就需要重新写了,如果用someip就不一样,只需要把服务部署到别的芯片,代码基本不用动,当然Binder也在慢慢支持基于网络的通信。

七、Android中丰富多彩的跨进程通信

Binder 三大定律

1.通过IBinder对象(Binder或者BinderProxy)可以调用Binder对象的接口 2.通过Binder接口可以传递基础数据,IBinder,FD 3.世界上第一个Binder对象就是SM

Binder支持fd的传递

socket,pipe,ion可都是基于fd,Binder成为了这些跨进程通信的fd对象的媒介,从而形成了丰富多彩的跨进程通信

pipe-vsync信号

socket-inputchannel

ion-surface对应的某个buffer

总结

本文的内容可能跳跃的比较厉害,但是其实是我对Binder通信的一些心得体会,有些内容可能你一下子无法理解,但是我相信你真的搞懂Binder后,再回过来我这篇文章,应该会认同的我的观点。

尾巴

这个问题其实也没有完美的答案,有时候思考问题的过程,比得到问题的答案更重要。

0 人点赞