【问题标题】:Advantages of using Binder for IPC in Android在 Android 中使用 Binder for IPC 的优势
【发布时间】:2011-11-20 03:00:27
【问题描述】:

在 Android 堆栈中使用 Binder for IPC 相比(信号量、消息队列、PIPES)有什么优势?

【问题讨论】:

  • 如果您选择一个正确的答案会有所帮助。
  • Android 开发人员和 Kernel 开发人员在 2009 年 6 月讨论了 LKML 上的 binder 与替代方案(也可能在其他时间点),从这两个角度进行了丰富的阅读,并解决了细节比目前在此发布的更准确。

标签: android android-binder


【解决方案1】:

Binders 用于启用远程过程调用。您可以使用您提到的同步工具来实现 RPC,但您还需要编写大量代码才能将其组合在一起......使用 Binder(通常仅在 Android 服务中使用),您编写的代码要少得多;仅比您实际的远程功能多一点。

【讨论】:

  • Binder 是否适合流高带宽、进程之间的低延迟数据(如音频或视频流?)
【解决方案2】:

Binders 用于跨进程边界进行通信,因为不同的进程不共享公共 VM 上下文 => 不再直接访问彼此的对象(内存)。同一进程中的双方(通常是同一应用程序中的事物)意味着(恕我直言)您不应该使用 Binder,因为它们会减慢/复杂化不必要的事情。

Binders 通常不直接使用,而是通过“Service”或“Messenger”类使用。虽然与服务的通信是通过完整的功能 API 完成的,但与 Messenger 的通信必须使用“消息”。 Messenger 的实现要简单得多。

除了使用 Binder,您还可以使用任何 VM 实例中可用的任何内容,例如“LocalSocket”、文件、ContentProviders、Intents...

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

【讨论】:

  • “同一进程中的双方(通常是同一个应用程序中的事物)意味着(恕我直言)您不应该使用 Binder,因为它们会减慢/使不必要的事情复杂化。” Intents 实际上是一个 Binder 抽象,所以不可能更快。
  • @littleScala 你是对的。同样ContentProvider 在跨进程边界使用时也使用Binder。我的回答有点糟糕:)
  • 请注意,android.os.Binder object 不同于Binder IPC 机制(即/dev/binder 及其用户模式包装等)
  • @ChrisStratton 我想我一直认为这个问题是关于android.os.Binder 的。但你是对的,它与“机制”不同(参见newandroidbook.com/files/Andevcon-Binder.pdf p.24 的全部内容),但/dev/binder 也不是用户空间包装(android.os.Binder 实际上不是其中之一吗? ) 就可以了。
【解决方案3】:

来自 ndk 的 docs/system/libc/SYSV-IPC.html 文件:

Android 不支持 System V IPC,即以下标准 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 的内核全局表将填满 起来。

此时,可能会发生奇怪的故障,并阻止使用它们的程序正常运行,直到系统下次重新启动。

【讨论】:

    【解决方案4】:

    老问题(并且可能没有被发帖人关注),但值得回答:

    A) 所有基于文件系统或文件系统可表示的 IPC 机制(特别是管道)都不能使用,因为缺少全局可写目录,所有进程都可以在该目录中 mkfifo/创建它们的文件系统/套接字表示IPC 端口(尽管 /dev/socket 用于系统进程,例如 rile、zygote 等)。

    B) 建议的机制均不具备 Android 所需的“服务定位”功能。在 UNIX 中,有一个 RPC 端口映射器,而 Android 需要类似的功能。输入:ServiceManager,它可以使用 binder 注册为上下文管理器,以动态注册/查找服务句柄

    C) 对序列化有广泛的需求——无论是意图还是其他消息。 Binder 提供了 Parcel 抽象,Parcel.java 可以将其用于数据封送。

    D) SysV 有比 Lambada 先生的回答更重要的其他问题,尤其是竞争条件和缺乏授权。

    E) 消息队列和管道不能传递描述符。 UNIX 域套接字可以使用,但不能使用,因为 (A)(同样,除非您是 root/系统,例如 zygote、rild、installd..)

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

    还有——别忘了

    G) Binder 是在 Palm 上启动的(啊,怀旧)(q.v. OpenBinder)。前掌门人进入了 Android,并带来了他们的代码。

    【讨论】:

      猜你喜欢
      • 2016-11-02
      • 1970-01-01
      • 1970-01-01
      • 2011-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-07
      相关资源
      最近更新 更多