Androidスタックで(セマフォ、メッセージキュー、パイプ)よりもIPCにバインダーを使用する利点は何ですか?
4 に答える
古い質問(そしておそらくポスターによって監視されていない)ですが、答える価値があります:
A) すべてのプロセスが IPC ポートのファイルシステム/ソケット表現を mkfifo/作成できる、誰でも書き込み可能なディレクトリがないため、すべてのファイルシステムベースまたはファイルシステム表現可能な IPC メカニズム (特にパイプ) は使用できません ( /dev/socket に関係なく、システム プロセス (rile、zygote、およびそれらの同類など) に使用されます)。
B) 提案されたメカニズムのいずれにも、Android に必要な「サービスの場所」の機能がありません。UNIX には RPC ポートマッパーがあり、Android にも同様の機能が必要です。入力: バインダーを使用してコンテキスト マネージャーとして登録し、その場でサービス ハンドルを登録/検索できる ServiceManager
C) インテントであれ、その他のメッセージであれ、シリアライゼーションの広範なニーズがあります。Binder は、Parcel.java によるデータ マーシャリングに使用できるパーセルの抽象化を提供します。
D) SysV には、ランバダ氏の回答以外にも、より重要な問題、特に競合状態と承認の欠如があります。
E) メッセージ キューとパイプは記述子を渡すことができません。UNIX ドメイン ソケットは使用できますが、(A) の理由で使用できません (繰り返しになりますが、zygote、rild、installd などのルート/システムでない限り)。
F) Binder は非常に軽量で、認証メカニズムが組み込まれています。また、受信者プロセスのウェイクアップや、他のメカニズムにはないメモリ共有などの気の利いた機能も備えています。((A) の名前付きマッピングのファイルの問題のため、mmap(2) がないことを忘れないでください)。
そして - 忘れないようにしましょう
G) Binder は Palm で開始されました (ああ、懐かしさ) (qv OpenBinder)。元パーマーは Android にアクセスし、自分たちのコードを持ち込みました。
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 の実装に使用されるカーネル グローバル テーブルがいっぱいになる可能性が非常に高いことを意味します。
その時点で、奇妙な障害が発生する可能性があり、システムの次の再起動まで、それらを使用するプログラムが適切に実行されなくなります。
異なるプロセスが共通の VM コンテキストを共有しないため、バインダはプロセスの境界を越えて通信するために使用されます => お互いのオブジェクト (メモリ) に直接アクセスできなくなります。同じプロセス内の両当事者 (通常は同じアプリ内のもの) は、不要なものを遅くしたり複雑にしたりするため、バインダーを使用しないでください (imho) ことを意味します。
通常、バインダーは直接使用されるのではなく、"Service" または "Messenger" クラスを介して使用されます。サービスとの通信は関数の完全な API を介して行われますが、メッセンジャーとの通信は「メッセージ」を使用する必要があります。メッセンジャーは実装がはるかに簡単です。
バインダーの使用とは別に、「LocalSocket」、ファイル、ContentProviders、Intents など、任意の VM インスタンスから利用できるものはすべて使用できます。
バインダーは、すべてのオブジェクトをパーセルに変換する (およびパーセルから戻す) 必要があるため、大きなデータ ストリーム (オーディオ/ビデオなど) の転送には適していません。すべての変換には時間がかかります。その場合、たとえば LocalSocket の方がはるかに優れています。
バインダーは、リモート プロシージャ コールを有効にするために使用されます。あなたが言及した同期ツールを使用してRPCを実装することもできますが、それをまとめるために多くのコードを書く必要もあります...バインダー(通常はAndroidサービス内でのみ使用されます)を使用すると、書くコードがはるかに少なくなります。実際のリモート機能よりもわずかに多くなります。