騰訊---Linux自帶多種進程通信方式,爲什麼Android都沒采用二偏偏使用Binder通信

 

面試官: Linux自帶多種進程通信方式,爲什麼Android都沒采用而偏偏使用Binder通信

心理分析:面試官絕對不會現場讓你分析binder的源碼,源碼又深又廣,沒有面試官會傻到讓你分析binder所有的機制。他會問你爲什麼不採用linux。 從這個地方會看出你對binder有多深。這道題往往是面試Android高級的必考題。所以小夥伴們需要格外的注意

**求職者:**應該從 linux自帶的進程通信說起。然後各個擊破 指出在Android這種特殊系統上的不足。最後引入binder的優勢

Linux現有的所有進程間IPC方式:

  1. 管道:

    什麼是管道:

    管道可用於具有親緣關係進程間的通信,管道是由內核管理的一個緩衝區,

    相當於我們放入內存中的一個紙條。管道的一端連接一個進程的輸出。這個進程會向管道中放入信息。

    管道的另一端連接一個進程的輸入,這個進程取出被放入管道的信息。一個緩衝區不需要很大,它被設計成爲環形的數據結構

     

    以便管道可以被循環利用。當管道中沒有信息的話,從管道中讀取的進程會等待,直到另一端的進程放入信息。當管道被放滿信息的時候,嘗試放入信息的進程會等待,直到另一端的進程取出信息。當兩個進程都終結的時候,管道也自動消失。

    缺點: 在創建時分配一個管道時,緩存區大小比較有限;並不適合Android大量的進程通信

  2. 消息隊列

    ​ 消息隊列提供了一種從一個進程向另一個進程發送一個數據塊的方法。 每個數據塊都被認爲含有一個類型,接收進程可以獨立地接收含有不同類型的數據結構。我們可以通過發送消息來避免命名管道的同步和阻塞問題。但是消息隊列與命名管道一樣,每個數據塊都有一個最大長度的限制。

    缺點: 信息複製兩次,額外的CPU消耗;不合適頻繁或信息量大的通信;

  3. 共享內存:

    ​ 什麼是共享內存:

    ​ 顧名思義,共享內存就是允許兩個不相關的進程訪問同一個邏輯內存。共享內存是在兩個正在運行的進程之間共享和傳遞數據的一種非常有效的方式。不同進程之間共享的內存通常安排爲同一段物理內存。進程可以將同一段共享內存連接到它們自己的地址空間中,所有進程都可以訪問共享內存中的地址

    無須複製,共享緩衝區直接付附加到進程虛擬地址空間,速度快

    缺點: 通信需要設計複雜的機制保證各個進程通訊有效性。進程間的同步問題操作系統無法實現,必須各進程利用同步工具解決; 安全問題比較突出,如果Android採用Binder 無異於將每個App放在一個內存中,這樣是非常不安全的

  4. **套接字:**作爲更通用的接口,傳輸效率低,主要用於不通機器或跨網絡的通信;

  5. **信號量:**常作爲一種鎖機制,防止某進程正在訪問共享資源時,其他進程也訪問該資源。因此,主要作爲進程間以及同一進程內不同線程之間的同步手段。

  6. 信號: 不適用於信息交換,更適用於進程中斷控制,比如非法內存訪問,殺死某個進程等;

接下來正面回答這個問題,從5個角度來展開對Binder的分析:

(1) 從性能的角度 數據拷貝次數:Binder數據拷貝只需要一次,而管道、消息隊列、Socket都需要2次,但共享內存方式一次內存拷貝都不需要;從性能角度看,Binder性能僅次於共享內存。

(2) 從穩定性的角度 Binder是基於C/S架構的,簡單解釋下C/S架構,是指客戶端(Client)和服務端(Server)組成的架構,Client端有什麼需求,直接發送給Server端去完成,架構清晰明朗,Server端與Client端相對獨立,穩定性較好;而共享內存實現方式複雜,沒有客戶與服務端之別, 需要充分考慮到訪問臨界資源的併發同步問題,否則可能會出現死鎖等問題;從這穩定性角度看,Binder架構優越於共享內存。

僅僅從以上兩點,各有優劣,還不足以支撐google去採用binder的IPC機制,那麼更重要的原因是:

(3) 從安全的角度 傳統Linux IPC的接收方無法獲得對方進程可靠的UID/PID,從而無法鑑別對方身份;而Android作爲一個開放的開源體系,擁有非常多的開發平臺,App來源甚廣,因此手機的安全顯得額外重要;對於普通用戶,絕不希望從App商店下載偷窺隱射數據、後臺造成手機耗電等等問題,傳統Linux IPC無任何保護措施,完全由上層協議來確保。

Android爲每個安裝好的應用程序分配了自己的UID,故進程的UID是鑑別進程身份的重要標誌,前面提到C/S架構,Android系統中對外只暴露Client端,Client端將任務發送給Server端,Server端會根據權限控制策略,判斷UID/PID是否滿足訪問權限,目前權限控制很多時候是通過彈出權限詢問對話框,讓用戶選擇是否運行。Android 6.0,也稱爲Android M,在6.0之前的系統是在App第一次安裝時,會將整個App所涉及的所有權限一次詢問,只要留意看會發現很多App根本用不上通信錄和短信,但在這一次性權限權限時會包含進去,讓用戶拒絕不得,因爲拒絕後App無法正常使用,而一旦授權後,應用便可以胡作非爲。

針對這個問題,google在Android M做了調整,不再是安裝時一併詢問所有權限,而是在App運行過程中,需要哪個權限再彈框詢問用戶是否給相應的權限,對權限做了更細地控制,讓用戶有了更多的可控性,但**同時也帶來了另一個用戶詬病的地方,那也就是權限詢問的彈框的次數大幅度增多。**對於Android M平臺上,有些App開發者可能會寫出讓手機異常頻繁彈框的App,企圖直到用戶授權爲止,這對用戶來說是不能忍的,用戶最後吐槽的可不光是App,還有Android系統以及手機廠商,有些用戶可能就跳果粉了,這還需要廣大Android開發者以及手機廠商共同努力,共同打造安全與體驗俱佳的Android手機。

傳統IPC只能由用戶在數據包裏填入UID/PID;另外,可靠的身份標記只有由IPC機制本身在內核中添加。其次傳統IPC訪問接入點是開放的,無法建立私有通道。從安全角度,Binder的安全性更高。

說到這,可能有人要反駁,Android就算用了Binder架構,而現如今Android手機的各種流氓軟件,不就是幹着這種偷窺隱射,後臺偷偷跑流量的事嗎?沒錯,確實存在,但這不能說Binder的安全性不好,因爲Android系統仍然是掌握主控權,可以控制這類App的流氓行爲,只是對於該採用何種策略來控制,在這方面android的確存在很多有待進步的空間,這也是google以及各大手機廠商一直努力改善的地方之一。在Android 6.0,google對於app的權限問題作爲較多的努力,大大收緊的應用權限;另外,在Google舉辦的Android Bootcamp 2016大會中,google也表示在Android 7.0 (也叫Android N)的權限隱私方面會進一步加強加固,比如SELinux,Memory safe language(還在research中)等等,在今年的5月18日至5月20日,google將推出Android N。

話題扯遠了,繼續說Binder。

(4)從語言層面的角度 大家多知道Linux是基於C語言(面向過程的語言),而Android是基於Java語言(面向對象的語句),而對於Binder恰恰也符合面向對象的思想,將進程間通信轉化爲通過對某個Binder對象的引用調用該對象的方法,而其獨特之處在於Binder對象是一個可以跨進程引用的對象,它的實體位於一個進程中,而它的引用卻遍佈於系統的各個進程之中。可以從一個進程傳給其它進程,讓大家都能訪問同一Server,就像將一個對象或引用賦值給另一個引用一樣。Binder模糊了進程邊界,淡化了進程間通信過程,整個系統彷彿運行於同一個面向對象的程序之中。從語言層面,Binder更適合基於面嚮對象語言的Android系統,對於Linux系統可能會有點“水土不服”。

另外,Binder是爲Android這類系統而生,而並非Linux社區沒有想到Binder IPC機制的存在,對於Linux社區的廣大開發人員,我還是表示深深佩服,讓世界有了如此精湛而美妙的開源系統。也並非Linux現有的IPC機制不夠好,相反地,經過這麼多優秀工程師的不斷打磨,依然非常優秀,每種Linux的IPC機制都有存在的價值,同時在Android系統中也依然採用了大量Linux現有的IPC機制,根據每類IPC的原理特性,因時制宜,不同場景特性往往會採用其下最適宜的。比如在Android OS中的Zygote進程的IPC採用的是Socket(套接字)機制,Android中的Kill Process採用的signal(信號)機制等等。而Binder更多則用在system_server進程與上層App層的IPC交互

(5) 從公司戰略的角度

總所周知,Linux內核是開源的系統,所開放源代碼許可協議GPL保護,該協議具有“病毒式感染”的能力,怎麼理解這句話呢?受GPL保護的Linux Kernel是運行在內核空間,對於上層的任何類庫、服務、應用等運行在用戶空間,一旦進行SysCall(系統調用),調用到底層Kernel,那麼也必須遵循GPL協議。

而Android 之父 Andy Rubin對於GPL顯然是不能接受的,爲此,Google巧妙地將GPL協議控制在內核空間,將用戶空間的協議採用Apache-2.0協議(允許基於Android的開發商不向社區反饋源碼),同時在GPL協議與Apache-2.0之間的Lib庫中採用BSD證授權方法,有效隔斷了GPL的傳染性,仍有較大爭議,但至少目前緩解Android,讓GPL止步於內核空間,這是Google在GPL Linux下 開源與商業化共存的一個成功典範。

有了這些鋪墊,我們再說說Binder的今世前緣

Binder是基於開源的 OpenBinder實現的,OpenBinder是一個開源的系統IPC機制,最初是由 Be Inc.開發,接着由Palm, Inc.公司負責開發,現在OpenBinder的作者在Google工作,既然作者在Google公司,在用戶空間採用Binder 作爲核心的IPC機制,再用Apache-2.0協議保護,自然而然是沒什麼問題,減少法律風險,以及對開發成本也大有裨益的,那麼從公司戰略角度,Binder也是不錯的選擇。

另外,再說一點關於OpenBinder,在2015年OpenBinder以及合入到Linux Kernel主線 3.19版本,這也算是Google對Linux的一點回饋吧。

綜合上述5點,可知Binder是Android系統上層進程間通信的不二選擇。

 

扣扣掃碼加入粉絲交流羣,即可領取福利

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