為什么 Android 要采用 Binder 作為 IPC 機制袁翁?

有網(wǎng)友問到:“Android另起爐灶開發(fā)了Binder驅動,而沒有采用已有的方案婿脸,而D-Bus這樣的方案也可以實現(xiàn)Binder的功能粱胜,是出于什么原因和什么考慮?安全性狐树?性能焙压?”

在開始回答前,先簡單概括性地說說

Linux現(xiàn)有的所有進程間IPC方式:
  1. 管道:在創(chuàng)建時分配一個page大小的內存抑钟,緩存區(qū)大小比較有限涯曲;

  2. 消息隊列:信息復制兩次,額外的CPU消耗味赃;不合適頻繁或信息量大的通信掀抹;

  3. 共享內存:無須復制,共享緩沖區(qū)直接付附加到進程虛擬地址空間心俗,速度快傲武;但進程間的同步問題操作系統(tǒng)無法實現(xiàn),必須各進程利用同步工具解決城榛;

  4. 套接字:作為更通用的接口揪利,傳輸效率低,主要用于不通機器或跨網(wǎng)絡的通信狠持;

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

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

Android的內核也是基于Linux內核祥绞,為何不直接采用Linux現(xiàn)有的進程IPC方案呢,難道Linux社區(qū)那么多優(yōu)秀人員都沒有考慮到有Binder這樣一個更優(yōu)秀的方案,是google太過于牛B嗎蜕径?事實是真相并非如此两踏,請細細往下看,您就明白了兜喻。

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

1.從性能的角度

數(shù)據(jù)拷貝次數(shù):Binder數(shù)據(jù)拷貝只需要一次,而管道虹统、消息隊列弓坞、Socket都需要2次,但共享內存方式一次內存拷貝都不需要车荔;從性能角度看渡冻,Binder性能僅次于共享內存。

2.從穩(wěn)定性的角度

Binder是基于C/S架構的忧便,簡單解釋下C/S架構族吻,是指客戶端(Client)和服務端(Server)組成的架構,Client端有什么需求珠增,直接發(fā)送給Server端去完成超歌,架構清晰明朗,Server端與Client端相對獨立蒂教,穩(wěn)定性較好巍举;而共享內存實現(xiàn)方式復雜,沒有客戶與服務端之別凝垛, 需要充分考慮到訪問臨界資源的并發(fā)同步問題懊悯,否則可能會出現(xiàn)死鎖等問題;從這穩(wěn)定性角度看梦皮,Binder架構優(yōu)越于共享內存炭分。

僅僅從以上兩點,各有優(yōu)劣剑肯,還不足以支撐google去采用binder的IPC機制捧毛,那么更重要的原因是:

3.從安全的角度

傳統(tǒng)Linux IPC的接收方無法獲得對方進程可靠的UID/PID,從而無法鑒別對方身份让网;而Android作為一個開放的開源體系呀忧,擁有非常多的開發(fā)平臺,App來源甚廣溃睹,因此手機的安全顯得額外重要而账;對于普通用戶,絕不希望從App商店下載偷窺隱射數(shù)據(jù)丸凭、后臺造成手機耗電等等問題福扬,傳統(tǒng)Linux IPC無任何保護措施,完全由上層協(xié)議來確保惜犀。

Android為每個安裝好的應用程序分配了自己的UID铛碑,故進程的UID是鑒別進程身份的重要標志,前面提到C/S架構虽界,Android系統(tǒng)中對外只暴露Client端汽烦,Client端將任務發(fā)送給Server端,Server端會根據(jù)權限控制策略莉御,判斷UID/PID是否滿足訪問權限撇吞,目前權限控制很多時候是通過彈出權限詢問對話框,讓用戶選擇是否運行礁叔。Android 6.0牍颈,也稱為Android M,在6.0之前的系統(tǒng)是在App第一次安裝時琅关,會將整個App所涉及的所有權限一次詢問煮岁,只要留意看會發(fā)現(xiàn)很多App根本用不上通信錄和短信,但在這一次性權限權限時會包含進去涣易,讓用戶拒絕不得画机,因為拒絕后App無法正常使用,而一旦授權后新症,應用便可以胡作非為步氏。

針對這個問題,google在Android M做了調整徒爹,不再是安裝時一并詢問所有權限荚醒,而是在App運行過程中,需要哪個權限再彈框詢問用戶是否給相應的權限瀑焦,對權限做了更細地控制腌且,讓用戶有了更多的可控性,但同時也帶來了另一個用戶詬病的地方榛瓮,那也就是權限詢問的彈框的次數(shù)大幅度增多铺董。對于Android M平臺上,有些App開發(fā)者可能會寫出讓手機異常頻繁彈框的App禀晓,企圖直到用戶授權為止精续,這對用戶來說是不能忍的,用戶最后吐槽的可不光是App粹懒,還有Android系統(tǒng)以及手機廠商重付,有些用戶可能就跳果粉了,這還需要廣大Android開發(fā)者以及手機廠商共同努力凫乖,共同打造安全與體驗俱佳的Android手機确垫。

傳統(tǒng)IPC只能由用戶在數(shù)據(jù)包里填入UID/PID弓颈;另外,可靠的身份標記只有由IPC機制本身在內核中添加删掀。其次傳統(tǒng)IPC訪問接入點是開放的翔冀,無法建立私有通道。從安全角度披泪,Binder的安全性更高纤子。

說到這,可能有人要反駁款票,Android就算用了Binder架構控硼,而現(xiàn)如今Android手機的各種流氓軟件,不就是干著這種偷窺隱射艾少,后臺偷偷跑流量的事嗎卡乾?沒錯,確實存在缚够,但這不能說Binder的安全性不好说订,因為Android系統(tǒng)仍然是掌握主控權,可以控制這類App的流氓行為潮瓶,只是對于該采用何種策略來控制陶冷,在這方面android的確存在很多有待進步的空間,這也是google以及各大手機廠商一直努力改善的地方之一毯辅。在Android 6.0埂伦,google對于app的權限問題作為較多的努力,大大收緊的應用權限思恐;另外沾谜,在Google舉辦的Android Bootcamp 2016大會中,google也表示在Android 7.0 (也叫Android N)的權限隱私方面會進一步加強加固胀莹,比如SELinux基跑,Memory safe language(還在research中)等等,在今年描焰,google推出了Android N媳否。

話題扯遠了,繼續(xù)說Binder荆秦。

4.從語言層面的角度

大家多知道Linux是基于C語言(面向過程的語言)篱竭,而Android是基于Java語言(面向對象的語句),而對于Binder恰恰也符合面向對象的思想步绸,將進程間通信轉化為通過對某個Binder對象的引用調用該對象的方法掺逼,而其獨特之處在于Binder對象是一個可以跨進程引用的對象,它的實體位于一個進程中瓤介,而它的引用卻遍布于系統(tǒng)的各個進程之中吕喘∽改牵可以從一個進程傳給其它進程,讓大家都能訪問同一Server氯质,就像將一個對象或引用賦值給另一個引用一樣漓概。Binder模糊了進程邊界,淡化了進程間通信過程病梢,整個系統(tǒng)仿佛運行于同一個面向對象的程序之中。從語言層面返干,Binder更適合基于面向對象語言的Android系統(tǒng)键痛,對于Linux系統(tǒng)可能會有點“水土不服”丝里。

另外,Binder是為Android這類系統(tǒng)而生钮热,而并非Linux社區(qū)沒有想到Binder IPC機制的存在,對于Linux社區(qū)的廣大開發(fā)人員烛芬,我還是表示深深佩服隧期,讓世界有了如此精湛而美妙的開源系統(tǒng)。也并非Linux現(xiàn)有的IPC機制不夠好赘娄,相反地仆潮,經(jīng)過這么多優(yōu)秀工程師的不斷打磨,依然非常優(yōu)秀遣臼,每種Linux的IPC機制都有存在的價值性置,同時在Android系統(tǒng)中也依然采用了大量Linux現(xiàn)有的IPC機制,根據(jù)每類IPC的原理特性揍堰,因時制宜鹏浅,不同場景特性往往會采用其下最適宜的。比如在Android OS中的Zygote進程的IPC采用的是Socket(套接字)機制屏歹,Android中的Kill Process采用的signal(信號)機制等等隐砸。而Binder更多則用在system_server進程與上層App層的IPC交互。

5.從公司戰(zhàn)略的角度

總所周知蝙眶,Linux內核是開源的系統(tǒng)季希,所開放源代碼許可協(xié)議GPL保護,該協(xié)議具有“病毒式感染”的能力幽纷,怎么理解這句話呢胖眷?受GPL保護的Linux Kernel是運行在內核空間,對于上層的任何類庫霹崎、服務珊搀、應用等運行在用戶空間,一旦進行SysCall(系統(tǒng)調用)尾菇,調用到底層Kernel境析,那么也必須遵循GPL協(xié)議囚枪。

而Android 之父 Andy Rubin對于GPL顯然是不能接受的,為此劳淆,Google巧妙地將GPL協(xié)議控制在內核空間链沼,將用戶空間的協(xié)議采用Apache-2.0協(xié)議(允許基于Android的開發(fā)商不向社區(qū)反饋源碼),同時在GPL協(xié)議與Apache-2.0之間的Lib庫中采用BSD證授權方法沛鸵,有效隔斷了GPL的傳染性括勺,仍有較大爭議,但至少目前緩解Android曲掰,讓GPL止步于內核空間疾捍,這是Google在GPL Linux下 開源與商業(yè)化共存的一個成功典范。

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

Binder是基于開源的 OpenBinder實現(xiàn)的乱豆,OpenBinder是一個開源的系統(tǒng)IPC機制,最初是由 Be Inc. 開發(fā),接著由Palm, Inc.公司負責開發(fā)吊趾,現(xiàn)在OpenBinder的作者在Google工作宛裕,既然作者在Google公司,在用戶空間采用Binder 作為核心的IPC機制论泛,再用Apache-2.0協(xié)議保護揩尸,自然而然是沒什么問題,減少法律風險屁奏,以及對開發(fā)成本也大有裨益的疲酌,那么從公司戰(zhàn)略角度,Binder也是不錯的選擇了袁。

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

綜合上述5點,可知Binder是Android系統(tǒng)上層進程間通信的不二選擇崭庸。

接著怀浆,討論下網(wǎng)友提到的D-Bus

也采用C/S架構的IPC機制,D-Bus是在用戶空間實現(xiàn)的方法怕享,效率低执赡,消息拷貝次數(shù)和上下文切換次數(shù)都明顯多過于Binder。針對D-Bus這些缺陷函筋,于是就產(chǎn)生了kdbus沙合,這是D-Bus在內核實現(xiàn)版,效率得到提升跌帐,與Binder一樣在內核作為字符設計首懈,通過open()打開設備绊率,mmap()映射內存。

(1)kdbus在進程間通信過程究履,Client端將消息在內存的消息隊列滤否,可以存儲大量的消息,Server端不斷從消息隊里中取消息最仑,大小只受限內存藐俺;

(2)Binder的機制是每次通信,會通信的進程或線程中的todo隊里中增加binder事務泥彤,并且每個進程所允許Binder線程數(shù)欲芹,google提供的默認最大線程數(shù)為16個,受限于CPU全景,由于線程數(shù)太多,增加系統(tǒng)負載牵囤,并且每個進程默認分配內存爸黄。

而kdbus對于內存消耗較大,同時也適合傳輸大量數(shù)據(jù)和大量消息的系統(tǒng)揭鳞。Binder對CPU和內存的需求比較低炕贵,效率比較高,從而進一步說明Binder適合于移動系統(tǒng)Android野崇,但是称开,也有一定缺點,就是不同利用Binder輸出大數(shù)據(jù)乓梨,比如利用Binder傳輸幾M大小的圖片鳖轰,便會出現(xiàn)異常,雖然有廠商會增加Binder內存扶镀,但是也不可能比系統(tǒng)默認內存大很多蕴侣,否則整個系統(tǒng)的可用內存大幅度降低。

最后臭觉,簡單講講Android Binder架構

Binder在Android系統(tǒng)中江湖地位非常之高昆雀。在Zygote孵化出system_server進程后,在system_server進程中出初始化支持整個Android framework的各種各樣的Service蝠筑,而這些Service從大的方向來劃分狞膘,分為Java層Framework和Native Framework層(C++)的Service,幾乎都是基于BInder IPC機制什乙。

1.Java framework:作為Server端繼承(或間接繼承)于Binder類挽封,Client端繼承(或間接繼承)于BinderProxy類。例如 ActivityManagerService(用于控制Activity臣镣、Service场仲、進程等) 這個服務作為Server端和悦,間接繼承Binder類,而相應的ActivityManager作為Client端渠缕,間接繼承于BinderProxy類鸽素。 當然還有PackageManagerService、WindowManagerService等等很多系統(tǒng)服務都是采用C/S架構亦鳞;

2.Native Framework層:這是C++層馍忽,作為Server端繼承(或間接繼承)于BBinder類,Client端繼承(或間接繼承)于BpBinder燕差。例如MediaPlayService(用于多媒體相關)作為Server端遭笋,繼承于BBinder類,而相應的MediaPlay作為Client端徒探,間接繼承于BpBinder類瓦呼。

總之,一句話"無Binder不Android"测暗。
總結來說:

1.首先澄清一點央串,Android沒有另起爐灶,Binder機制源于OpenBinder.

2.Binder與傳統(tǒng)IPC機制

那么碗啄,與Linux上傳統(tǒng)的IPC機制质和,比如System+V,Socket相比稚字,Binder好在哪呢饲宿?

性能;Binder傳輸只需要一次copy胆描;socket兩次瘫想,別小看這一倍帶來的差距。對于移動設備昌讲,性能一直是個大問題殿托;想一下Android繪制界面的時候都需要與WindowManager進行跨進程通信,如果這里效率不高剧蚣,那豈不是卡死支竹?

安全性;Binder機制對于通信雙方的身份是內核進行校檢支持的鸠按;socket方式只需要知道地址都可以連接礼搁;安全機制需要上層協(xié)議架設。

易用性目尖;共享內存不需要copy性能夠高馒吴,可是使用復雜;B%2FS模式的通信,如果管道%2F消息隊列還得進行包裝饮戳;另外豪治,Binder使用面向對象的方式設計,進行一次遠程過程調用就好像直接調用本地對象一樣扯罐,異常方便负拟。

另外,引用+Brian+Swetland+大神的回答:

大意就是:

1.避免內核空間到數(shù)據(jù)接受端的直接的數(shù)據(jù)拷貝歹河;數(shù)據(jù)接受端接收數(shù)據(jù)的時候掩浙,由于數(shù)據(jù)大小不確定,要么分配一個很大的空間裝數(shù)據(jù)秸歧,要么動態(tài)擴容厨姚;兩種方式都有問題;Binder使用mmap直接把接受端的內存映射到內存空間键菱,避免了數(shù)據(jù)的直接拷貝谬墙;另外通過data_buffer等方式讓數(shù)據(jù)僅包含定長的消息頭,解決了接受端內存分配的問題经备。

2.需要管理跨進程傳遞的代理對象的生命周期拭抬;這一點其他機制無法完成;Binder驅動通過引用計數(shù)技術解決這個問題弄喘。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末玖喘,一起剝皮案震驚了整個濱河市甩牺,隨后出現(xiàn)的幾起案子蘑志,更是在濱河造成了極大的恐慌,老刑警劉巖贬派,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件急但,死亡現(xiàn)場離奇詭異,居然都是意外死亡搞乏,警方通過查閱死者的電腦和手機波桩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來请敦,“玉大人镐躲,你說我怎么就攤上這事∈躺福” “怎么了萤皂?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長匣椰。 經(jīng)常有香客問我裆熙,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任入录,我火速辦了婚禮蛤奥,結果婚禮上,老公的妹妹穿的比我還像新娘僚稿。我一直安慰自己凡桥,他們只是感情好,可當我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布贫奠。 她就那樣靜靜地躺著唬血,像睡著了一般。 火紅的嫁衣襯著肌膚如雪唤崭。 梳的紋絲不亂的頭發(fā)上拷恨,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天,我揣著相機與錄音谢肾,去河邊找鬼腕侄。 笑死,一個胖子當著我的面吹牛芦疏,可吹牛的內容都是我干的冕杠。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼酸茴,長吁一口氣:“原來是場噩夢啊……” “哼分预!你這毒婦竟也來了?” 一聲冷哼從身側響起薪捍,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤笼痹,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后酪穿,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體凳干,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年被济,在試婚紗的時候發(fā)現(xiàn)自己被綠了救赐。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡只磷,死狀恐怖经磅,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情钮追,我是刑警寧澤预厌,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站畏陕,受9級特大地震影響配乓,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一犹芹、第九天 我趴在偏房一處隱蔽的房頂上張望崎页。 院中可真熱鬧,春花似錦腰埂、人聲如沸飒焦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽牺荠。三九已至,卻和暖如春驴一,著一層夾襖步出監(jiān)牢的瞬間休雌,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工肝断, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留杈曲,地道東北人。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓胸懈,卻偏偏與公主長得像担扑,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子趣钱,可洞房花燭夜當晚...
    茶點故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內容