使用Binder进行Android IPC的优势

17
使用 Binder 进行 Android IPC 比使用信号量、消息队列和管道的优势是什么?

1
如果您能选择正确的答案,那将有所帮助。 - JohnnyLambada
Android开发人员和内核开发人员在2009年6月的LKML上就Binder与其他替代方案进行了讨论(可能也在其他时间点),这篇文章对于两种观点都具有启发性,比目前为止发布的内容更加准确地解决了细节问题。 - Chris Stratton
4个回答

23

旧问题(很可能已经没有人关注了),但值得回答:

A)所有基于文件系统或可表示为文件系统的IPC机制(特别是管道)都无法使用,因为缺少一个全局可写目录,所有进程都可以在其中创建他们的IPC端口的文件系统/套接字表示形式(除了/dev/socket之外,它用于系统进程,例如ril、zygote及其同类)。

B)建议的机制中没有“服务定位”功能,这是Android所必需的。在UNIX中,有一个RPC端口映射程序,Android需要类似的功能。引入ServiceManager,它可以使用binder注册为上下文管理器,在运行时注册/查找服务句柄。

C)需要大量的序列化——无论是意图还是其他消息。Binder提供了parcel抽象,可以由Parcel.java用于数据编组。

D)SysV存在比Lambada先生的答案更重要的其他问题,特别是竞争条件和缺乏授权。

E)消息队列和管道无法传递描述符。UNIX域套接字可能可以,但由于(A)而无法使用(除非您是像zygote、rild、installd等的root/system用户)。

F)Binder非常轻巧,并且具有内置的授权机制。它还具有一些巧妙的功能,例如唤醒接收进程以及内存共享,其他机制根本没有这些功能。 (请记住,在命名映射中由于(A)中的文件问题,没有mmap(2))。

并且-别忘了

G)Binder始于Palm(啊,怀旧),Ex-palmers来到Android,并将他们的代码带了进来。


6

根据ndk的文件docs/system/libc/SYSV-IPC.html

Android不支持System V IPCs,即以下标准Posix头文件提供的功能:

<sys/sem.h>   /* SysV semaphores */
<sys/shm.h>   /* SysV shared memory segments */
<sys/msg.h>   /* SysV message queues */
<sys/ipc.h>   /* General IPC definitions */

这是由于它们会导致全局内核资源泄漏的设计缘故。
例如,当一个有漏洞或恶意的进程退出、非有漏洞和恶意的进程崩溃或被显式杀死时,无法自动释放在内核中分配的SysV信号量。
为了为新应用程序腾出空间而自动杀死进程是Android应用程序生命周期实现的重要部分。这意味着即使只考虑没有漏洞和恶意代码,随着时间的推移,用于实现SysV IPC的内核全局表很可能会被填满。
此时,奇怪的故障可能会发生,并防止使用它们运行正确的程序,直到下一次系统重启。

1

绑定器用于跨进程通信,因为不同的进程没有共享的VM上下文,所以不能直接访问彼此的对象(内存)。在同一进程中的双方(通常是同一应用程序中的事物)意味着您不应该使用绑定器,因为它们会使事情变得更加缓慢/复杂。

绑定器通常不是直接使用,而是通过“Service”或“Messenger”类使用。与服务的通信通过完整的函数API完成,而与Messenger的通信必须使用“Message”。Messenger实现起来要简单得多。

除了使用绑定器之外,您可以使用任何可从任何VM实例获得的内容,例如“LocalSocket”、“Files”、“ContentProviders”、“Intents”等。

绑定器不适合传输大型数据流(如音频/视频),因为每个对象都必须转换为(并从中返回)一个Parcel。所有的转换都需要时间。在这种情况下,更好的选择是例如LocalSocket。


在同一进程中的双方(通常是在同一个应用程序中的事物)意味着(在我看来)您不应该使用Binder,因为它们会使事情变得缓慢/复杂化,而Intent实际上是Binder的抽象,因此不太可能更快。 - user2476398
@littleScala 你说得对。当在进程边界上使用ContentProvider时,也会使用Binder。我的回答有点糟糕 :) - zapl
请注意,android.os.Binder 对象 是与 Binder IPC 机制(即 /dev/binder 及其用户模式包装等)不同的东西。 - Chris Stratton
@ChrisStratton 我一直认为这个问题特指 android.os.Binder。但你说得对,它并不等同于“机制”(参见 http://newandroidbook.com/files/Andevcon-Binder.pdf 第24页的全部内容),但 /dev/binder 或其用户空间包装也不是(android.os.Binder 实际上是其中之一吗?)。 - zapl

0

绑定器用于启用远程过程调用。您可以使用您提到的同步工具来实现RPC,但是您还需要编写大量代码才能使其协同工作...使用绑定器(通常仅在Android服务中使用),您需要编写的代码要少得多;几乎只有您实际的远程函数。


3
Binder是否适用于在进程之间流动高带宽、低延迟的数据(例如音频或视频流)? - user48956

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接