前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[083]Binder答疑解惑(一)

[083]Binder答疑解惑(一)

作者头像
王小二
发布2023-09-09 16:00:55
1780
发布2023-09-09 16:00:55
举报

问题

为什么已经有了管道等跨进程通信方式,却要另外创建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后,再回过来我这篇文章,应该会认同的我的观点。

尾巴

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-09-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题
    • 一、跨进程通信共性
      • 二、匿名管道(pipe)
        • 三、实名管道(fifo)
          • 四、Socket通信
            • 五、只有Binder能做到的事
              • 小结
                • 六、Binder的缺点
                  • 七、Android中丰富多彩的跨进程通信
                    • 总结
                      • 尾巴
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档