Binder的基本原理

多進程有哪些優點?

多進程一般在webView、圖片加載、推送、鬧鐘之類的比較常見,還有比如在使用getSystemService獲取系統服務的時候,雖然在自己寫的代碼中沒有發現多進程,其實在內部實現中也是多進程。

它們爲什麼需要被做成多進程的呢?

1、解決手機內存問題

雖然現在手機的運行內存是很大的,但是手機的APP是運行在獨立的虛擬機中的,虛擬機會爲每一個進程分配運行內存是有限的,一般只有32M、48M、64M,所以經常會發生一些內存不足的問題,就像加載一個大的圖片,可能就直接OOM。

2、其他進程崩潰,避免影響主進程

打個比方,就像是微信的小程序,微信小程序的開發者們水平參差不齊,如果有一個小程序崩潰了,微信的主進程是不會崩潰的,這就已經說明,微信的主進程與微信的小程序不在同一個進程中。

 

Binder是什麼?

1. Binder是一個實現了IBinder接口的類;

2. Binder是一種虛擬的物理設備,它的設備驅動是/dev/binder;

3. Binder是連接ServiceManager連接各種Manager和對應ManagerService的橋樑;

4. Binder是客戶端和服務端進行通信的媒介,當bindService時,服務端會返回一個包含了服務端業務調用的Binder對象,通過這個Binder對象,客戶端就可以獲取服務端提供的服務(普通服務、基於AIDL服務)或數據。

在Android中,Binder主要存在Service中,包括AIDL和Messenger。

 

兩進程之間如何進行通信?

從進程1的用戶空間到進程2的用戶空間,需要經過內核空間,數據從進程1的用戶空間先通過系統調用到達內核空間,然後從內核空間通過系統調用到達進程2的用戶空間,這就是數據的傳輸過程。

因爲進程1和進程2是兩個進程,所以他們的之間是隔離的,但是它們的內核空間它是一個整塊,他可以去隨意訪問進程。

 

Socket如何進行跨進程通信?

1、首先,發送方的進程先通過系統調用copy_from_user(),來將數據從用戶空間複製到內核緩存區中(這是第一次拷貝)。

2、然後,內核空間再通過系統調用copy_to_user(),將數據從內核緩存區中又拷貝到接收進程的用戶空間中(這是第二次拷貝)。

 

Binder如何進行跨進程通信?

1、當發送方進程將數據發送到內核空間的時候,與傳統IPC是一樣的,都是通過了系統調用copy_from_user()。

2、在內核空間與接收方的用戶空間之間,它是使用的映射來完成的。接收方進程和內核空間之間有一塊區域,它們兩個之間存在映射關係,就好比於,內核空間的那塊空間是一塊虛擬空間,用戶空間也是一塊虛擬空間,它們兩個空間都映射在了同一塊的物理空間,當數據傳入到了內核空間,也就相當於存在於內核空間的那塊物理空間,而這塊物理空間又同時被用戶空間這個虛擬空間所映射,所以也就相當於數據存在了用戶空間。

內存它會存在於一個虛擬空間和物理空間上,它們之間是有一個地址映射的關係,可能用戶空間映射在這,內核空間映射在那,另一個用戶空間又映射在別處,它們之間是分開的,沒有關聯的。

所以想要在他們三者之間數據傳遞的話,只能像傳統IPC那樣去copy兩次;而Binder,因爲它在接受方進程與內核空間之間通過MMap(Memory Map內存映射)有一個映射,也就是內核空間的虛擬內存與接受方用戶空間的虛擬內存映射同一塊物理空間,

虛擬空間:這裏所說的用戶空間和內核空間,其實都是虛擬空間,既然是虛擬空間,它就需要映射到物理空間上,因爲我們的數據都是保存在物理空間上的。

 

Binder既然內核空間於接收方內存空間使用映射,爲什麼不直接從發送方的用戶空間直接映射到接受方的用戶空間?

1、首先,如果就像問題所說,直接從用戶空間映射到了用戶空間,那其實就成了共享內存這個概念。爲什麼即使共享內存可以做到0拷貝,而Binder沒有選擇這個做法呢?

2、Binder是基於了C/S(Client/Server)架構的,使用起來非常簡單;而共享內存因爲兩塊虛擬內存共同映射在一塊物理空間,多進程共享同一塊內存區域,所以會有一些同步機制的問題,比如一些死鎖、數據不同步等問題,所以共享內存使用起來較爲複雜。這樣一來,Binder考慮到易用性方面,在性能方面也做了一些取捨。

 

Binder與傳統IPC之間的對比

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章