简体   繁体   English

在Android中使用Binder for IPC的优点

[英]Advantages of using Binder for IPC in Android

在Android堆栈中使用Binder for IPC(Semaphores,Message Queue,PIPES)有什么好处?

Old question (and likely unmonitored by the poster), but worth answering: 旧问题(可能不受海报监控),但值得回答:

A) All filesystem-based or filesystem-representable IPC mechanisms (notably pipes), can't be used because of a lack of a world-writable directory, where all processes can mkfifo/create the filesystem/socket representation of their IPC port (/dev/socket notwithstanding, which is used for system processes, eg rile, zygote, and their ilk). A)由于缺少一个可写入世界的目录,所有进程都可以mkfifo /创建其IPC端口的文件系统/套接字表示,因此无法使用所有基于文件系统或文件系统可表示的IPC机制(特别是管道)( / dev / socket尽管如此,它用于系统进程,例如rile,zygote和他们的同类)。

B) None of the suggested mechanisms have the capability of "service location" which is required for Android. B)所建议的机制都不具备Android所需的“服务定位”能力。 In UNIX, there's an RPC portmapper, and Android needs similar functionality. 在UNIX中,有一个RPC portmapper,Android需要类似的功能。 Enter: The ServiceManager, which can use binder to register as a context manager, to register/lookup service handles on the fly 输入:ServiceManager,可以使用binder注册为上下文管理器,即时注册/查找服务句柄

C) There is an extensive need for serialization - be it intents, or other messages. C)对序列化有广泛的需求 - 无论是意图还是其他消息。 Binder provides the parcel abstraction, which can be used for data marshaling by the Parcel.java. Binder提供parcel抽象,可用于Parcel.java的数据封送。

D) SysV has other issues than Mr. Lambada's answer which are more paramount, notably race conditions, and lack of authorization. D)SysV还有其他问题,而不是Lambada先生的答案,这些问题更为重要,特别是竞争条件和缺乏授权。

E) Message queues and pipes can't pass descriptors. E)消息队列和管道无法传递描述符。 UNIX Domain sockets may, but can't be used because of (A) (again, unless you're root/system, like zygote, rild, installd..) UNIX域套接字可能但由于(A)而无法使用(同样,除非你是root / system,如zygote,rild,installd ..)

F) Binder is really lightweight, and has built-in authorization mechanisms. F)Binder非常轻巧,并且内置授权机制。 It also has nifty features like waking up the recipient process, as well as memory sharing, which the other mechanisms simply don't have. 它还具有漂亮的功能,如唤醒收件人进程,以及内存共享,其他机制根本没有。 (and remember, no mmap(2), because of the file problem in (A) for named mappings). (并记住,没有mmap(2),因为(A)中的命名映射存在文件问题)。

and - let's not forget - 让我们不要忘记

G) Binder was started at Palm (ah, nostalgia) (qv OpenBinder). G)Binder是在Palm(啊,怀旧)(qv OpenBinder)开始的。 Ex-palmers got to Android, and brought their code in with them. Ex-palmers开始使用Android,并随身携带代码。

From the ndk's docs/system/libc/SYSV-IPC.html file: 从ndk的docs / system / libc / SYSV-IPC.html文件中:

Android does not support System V IPCs, ie the facilities provided by the following standard Posix headers: 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 */

The reason for this is due to the fact that, by design, they lead to global kernel resource leakage. 其原因在于,通过设计,它们导致全局内核资源泄漏。

For example, there is no way to automatically release a SysV semaphore allocated in the kernel when: 例如,在以下情况下,无法自动释放内核中分配的SysV信号量:

  • a buggy or malicious process exits 一个错误或恶意进程退出
  • a non-buggy and non-malicious process crashes or is explicitly killed. 非错误和非恶意进程崩溃或被明确杀死。

Killing processes automatically to make room for new ones is an important part of Android's application lifecycle implementation. 自动杀死进程以为新进程腾出空间是Android应用程序生命周期实现的重要组成部分。 This means that, even assuming only non-buggy and non-malicious code, it is very likely that over time, the kernel global tables used to implement SysV IPCs will fill up. 这意味着,即使只假设非错误和非恶意代码,很可能随着时间的推移,用于实现SysV IPC的内核全局表将填满。

At that point, strange failures are likely to occur and prevent programs that use them to run properly until the next reboot of the system. 此时,可能会发生奇怪的故障,并阻止使用它们的程序在下次重新引导系统之前正常运行。

Binders are used to to communicate over process boundaries since different processes don't share a common VM context => no more direct access to each others Objects (memory). 绑定器用于通过进程边界进行通信,因为不同的进程不共享公共VM上下文=>不再可以直接访问其他对象(内存)。 Both parties within the same process (usually things that are within the same app) means (imho) that you should not use Binders since they slow down / complexify things unnecessary. 同一过程中的双方(通常是在同一个应用程序中的东西)意味着(imho)你不应该使用Binders,因为它们会减慢/复杂化不必要的东西。

Binders are usually not used directly but rather via the "Service" or the "Messenger" classes. 粘合剂通常不是直接使用,而是通过“服务”或“Messenger”类。 While communication with a Service is done via a full api of functions, the communication with a Messenger has to use "Message"s. 虽然通过完整的功能API与服务进行通信,但与Messenger的通信必须使用“消息”。 Messengers a lot simpler to implement. 信使实施起来要简单得多。

Apart from using Binders you can use anything that is available from any VM instance like "LocalSocket"s, Files, ContentProviders, Intents, ... 除了使用Binders之外,您还可以使用任何VM实例中提供的任何内容,例如“LocalSocket”,Files,ContentProviders,Intents,...

Binders are not ideal for transferring large data streams (like audio/video) since every object has to be converted to (and back from) a Parcel. 由于每个对象都必须转换为包裹(并从包裹返回),因此粘合剂不适合传输大型数据流(如音频/视频)。 All the conversion takes time. 所有转换都需要时间。 Much better in that case would be a LocalSocket for example. 在这种情况下,更好的是例如LocalSocket。

Binders are used to enable remote procedure calls. 绑定器用于启用远程过程调用。 You could implement RPC using the synchronization tools you mention but you would also need to write a lot of code to make it come together... with a Binder (normally only used within an Android Service) you have much less code to write; 您可以使用您提到的同步工具实现RPC,但是您还需要编写大量代码才能将它组合在一起...使用Binder(通常仅在Android服务中使用),您可以编写更少的代码; barely more than your actual remote functions. 几乎不比你的实际远程功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM