一、什么是Binder
Binder,一個通過內存映射實現跨進程通信的東東,Android中一個進程空間分為用戶空間和內核空間,其中用戶空間數據不可共享,內核空間數據可共享。
因此跨進程通信需要內核空間的支持,傳統IPC通信例如管道,Socket等,它們是內核空間的一部分,可以直接拷貝,通過內容提供者進程copy_from_user()拷貝到內核空間,再通過copy_to_user()復制給內容接收方用戶空間,實現的進程間通信。
但是Binder不屬于Linux內核空間,不能直接進行內核空間的兩次拷貝,所以需要借助Linux的動態內核可加載模塊機制。
既然有現有的IPC方式,為什么重新設計一套Binder機制呢。主要是出于以上三個方面的考量:
高性能:從數據拷貝次數來看Binder只需要進行一次內存拷貝,而管道、消息隊列、Socket都需要兩次,共享內存不需要拷貝,Binder的性能僅次于共享內存。
穩定性:上面說到共享內存的性能優于Binder,那為什么不適用共享內存呢,因為共享內存需要處理并發同步問題,控制負責,容易出現死鎖和資源競爭,穩定性較差。而Binder基于C/S架構,客戶端與服務端彼此獨立,穩定性較好。
安全性:我們知道Android為每個應用分配了UID,用來作為鑒別進程的重要標志,Android內部也依賴這個UID進行權限管理,包括6.0以前的固定權限和6.0以后的動態權限,傳榮IPC只能由用戶在數據包里填入UID/PID,這個標記完全是在用戶空間控制的,沒有放在內核空間,因此有被惡意篡改的可能,因此Binder的安全性更高。
延伸閱讀:
二、傳統IPC通信方式
Linux現有的進程通信手段有以下幾種:
管道:在創建時分配一個page大小的內存,緩存區大小比較有限; 消息隊列:信息復制兩次,額外的CPU消耗;不合適頻繁或信息量大的通信;
共享內存:無須復制,共享緩沖區直接付附加到進程虛擬地址空間,速度快;但進程間的同步問題操作系統無法實現,必須各進程利用同步工具解決;
套接字:作為更通用的接口,傳輸效率低,主要用于不通機器或跨網絡的通信;
信號量:常作為一種鎖機制,防止某進程正在訪問共享資源時,其他進程也訪問該資源。因此,主要作為進程間以及同一進程內不同線程之間的同步手段;
信號: 不適用于信息交換,更適用于進程中斷控制,比如非法內存訪問,殺死某個進程等。