Android中的IPC方式——Binder(一)

本文主要是參考一些資料講述一些基本概念鹊汛,有基礎(chǔ)的可以直接從下一篇看起续扔。
只要有個(gè)基本的了解就可以了不必深究灯帮。

概述

簡(jiǎn)單來(lái)說(shuō),Binder是Android中使用最廣泛的IPC(進(jìn)程間通信)機(jī)制司致。Linux中本身已經(jīng)擁有了經(jīng)典的進(jìn)程間的通信方式,如信號(hào)量借帘、管道歌亲、消息隊(duì)列、貢獻(xiàn)內(nèi)存疾就、scoket等澜术。那么Android還是創(chuàng)造了新的IPC方式,主要是基于性能猬腰、穩(wěn)定性和安全性方面考慮鸟废。

  • 性能

    性能上的優(yōu)勢(shì)。Socket 作為一款通用接口姑荷,其傳輸效率低盒延,開(kāi)銷(xiāo)大,主要用在跨網(wǎng)絡(luò)的進(jìn)程間通信和本機(jī)上進(jìn)程間的低速通信鼠冕。消息隊(duì)列和管道采用存儲(chǔ)-轉(zhuǎn)發(fā)方式添寺,即數(shù)據(jù)先從發(fā)送方緩存區(qū)拷貝到內(nèi)核開(kāi)辟的緩存區(qū)中,然后再?gòu)膬?nèi)核緩存區(qū)拷貝到接收方緩存區(qū)懈费,至少有兩次拷貝過(guò)程计露。共享內(nèi)存雖然無(wú)需拷貝,但控制復(fù)雜,難以使用薄坏。Binder 只需要一次數(shù)據(jù)拷貝趋厉,性能上僅次于共享內(nèi)存。

    IPC方式 數(shù)據(jù)拷貝次數(shù)
    共享內(nèi)存 0
    Binder 1
    Socket/管道/消息隊(duì)列 2
  • 安全性

    傳統(tǒng)的 IPC 沒(méi)有任何安全措施胶坠,完全依賴(lài)上層協(xié)議來(lái)確保君账。Android 作為一個(gè)開(kāi)放性的平臺(tái),市場(chǎng)上有各類(lèi)海量的應(yīng)用供用戶(hù)選擇安裝沈善,所以Android 為每個(gè)安裝好的 APP 分配了自己的 UID乡数,故而進(jìn)程的 UID 是鑒別進(jìn)程身份的重要標(biāo)志來(lái)鑒別身份。

  • 穩(wěn)定性

    基于C/S架構(gòu)闻牡,客戶(hù)端有什么需求丟給服務(wù)端來(lái)處理净赴,架構(gòu)清晰、職責(zé)明確又相互獨(dú)立罩润,自然穩(wěn)定性更好玖翅。雖然貢獻(xiàn)內(nèi)存無(wú)需拷貝,但是控制復(fù)雜難以使用割以。

Linux進(jìn)程間通信

基本概念介紹

Linux

上圖展示了 Liunx 中跨進(jìn)程通信涉及到的一些基本概念:

  • 進(jìn)程隔離
    進(jìn)程與進(jìn)程間內(nèi)存是不共享的金度。兩個(gè)進(jìn)程就像兩個(gè)平行的世界,A 進(jìn)程沒(méi)法直接訪問(wèn) B 進(jìn)程的數(shù)據(jù)严沥,這就是進(jìn)程隔離的通俗解釋猜极。A 進(jìn)程和 B 進(jìn)程之間要進(jìn)行數(shù)據(jù)交互就得采用特殊的通信機(jī)制:進(jìn)程間通信(IPC)。

  • 進(jìn)程空間劃分
    操作系統(tǒng)的核心是內(nèi)核消玄,獨(dú)立于普通的應(yīng)用程序跟伏,可以訪問(wèn)受保護(hù)的內(nèi)存空間,也可以訪問(wèn)底層硬件設(shè)備的權(quán)限翩瓜。為了保護(hù)用戶(hù)進(jìn)程不能直接操作內(nèi)核受扳,保證內(nèi)核的安全,操作系統(tǒng)從邏輯上將虛擬空間劃分為用戶(hù)空間(User Space)和內(nèi)核空間(Kernel Space)奥溺。

  • 系統(tǒng)調(diào)用

    從邏輯上進(jìn)行了用戶(hù)空間和內(nèi)核空間的劃分辞色,但不可避免的用戶(hù)空間需要訪問(wèn)內(nèi)核資源,比如文件操作浮定、訪問(wèn)網(wǎng)絡(luò)等等相满。就需要借助系統(tǒng)調(diào)用來(lái)實(shí)現(xiàn),這樣保證了所有的資源訪問(wèn)都是在內(nèi)核的控制下進(jìn)行的桦卒,避免了用戶(hù)程序?qū)ο到y(tǒng)資源的越權(quán)訪問(wèn)立美,提升了系統(tǒng)安全性和穩(wěn)定性。

Linux 下的傳統(tǒng) IPC 通信原理

消息發(fā)送方將要發(fā)送的數(shù)據(jù)存放在內(nèi)存緩存區(qū)中方灾,通過(guò)系統(tǒng)調(diào)用進(jìn)入內(nèi)核態(tài)建蹄。然后內(nèi)核程序在內(nèi)核空間分配內(nèi)存碌更,開(kāi)辟一塊內(nèi)核緩存區(qū),調(diào)用 copy_from_user()函數(shù)將數(shù)據(jù)從用戶(hù)空間的內(nèi)存緩存區(qū)拷貝到內(nèi)核空間的內(nèi)核緩存區(qū)中洞慎。

同樣的痛单,接收方進(jìn)程在接收數(shù)據(jù)時(shí)在自己的用戶(hù)空間開(kāi)辟一塊內(nèi)存緩存區(qū),然后內(nèi)核程序調(diào)用copy_to_user()函數(shù)將數(shù)據(jù)從內(nèi)核緩存區(qū)拷貝到接收進(jìn)程的內(nèi)存緩存區(qū)劲腿。

傳統(tǒng) IPC 通信原理

傳統(tǒng)的 IPC 通信方式有兩個(gè)問(wèn)題:

  • 性能低下旭绒,一次數(shù)據(jù)傳遞需要經(jīng)歷:內(nèi)存緩存區(qū) --> 內(nèi)核緩存區(qū) --> 內(nèi)存緩存區(qū),需要 2 次數(shù)據(jù)拷貝
  • 接收數(shù)據(jù)的緩存區(qū)由數(shù)據(jù)接收進(jìn)程提供焦人,但是接收進(jìn)程并不知道需要多大的空間來(lái)存放將要傳遞過(guò)來(lái)的數(shù)據(jù)挥吵,因此只能開(kāi)辟盡可能大的內(nèi)存空間或者先調(diào)用 API 接收消息頭來(lái)獲取消息體的大小,這兩種做法不是浪費(fèi)空間就是浪費(fèi)時(shí)間花椭。

Binder 跨進(jìn)程通信原理

從上面看出傳統(tǒng)的跨進(jìn)程通信是需要內(nèi)核空間做支持的忽匈,但是Binder并不是Linux 系統(tǒng)內(nèi)核的一部分,這樣怎么辦呢矿辽? Linux 有動(dòng)態(tài)內(nèi)核可加載模塊(Loadable Kernel Module丹允,LKM)的機(jī)制,模塊是具有獨(dú)立功能的程序嗦锐,它可以被單獨(dú)編譯嫌松,但是不能獨(dú)立運(yùn)行沪曙。它在運(yùn)行時(shí)被鏈接到內(nèi)核作為內(nèi)核的一部分運(yùn)行奕污。這樣,Android 系統(tǒng)就可以通過(guò)動(dòng)態(tài)添加一個(gè)內(nèi)核模塊運(yùn)行在內(nèi)核空間液走,用戶(hù)進(jìn)程之間通過(guò)這個(gè)內(nèi)核模塊作為橋梁來(lái)實(shí)現(xiàn)通信碳默。

在 Android 系統(tǒng)中,這個(gè)運(yùn)行在內(nèi)核空間缘眶,負(fù)責(zé)各個(gè)用戶(hù)進(jìn)程通過(guò) Binder 實(shí)現(xiàn)通信的內(nèi)核模塊就叫 Binder 驅(qū)動(dòng)(Binder Dirver)嘱根。

Binder IPC 方式主要是通過(guò)內(nèi)存映射mmap() 來(lái)實(shí)現(xiàn),mmap() 是操作系統(tǒng)中一種內(nèi)存映射的方法巷懈。內(nèi)存映射簡(jiǎn)單的講就是將用戶(hù)空間的一塊內(nèi)存區(qū)域映射到內(nèi)核空間该抒。

內(nèi)存映射能減少數(shù)據(jù)拷貝次數(shù),實(shí)現(xiàn)用戶(hù)空間和內(nèi)核空間的高效互動(dòng)顶燕。兩個(gè)空間各自的修改能直接反映在映射的內(nèi)存區(qū)域凑保,從而被對(duì)方空間及時(shí)感知。也正因?yàn)槿绱擞抗ィ瑑?nèi)存映射能夠提供對(duì)進(jìn)程間通信的支持欧引。

一次完整的Binder IPC過(guò)程:

  • 首先 Binder 驅(qū)動(dòng)在內(nèi)核空間創(chuàng)建一個(gè)數(shù)據(jù)接收緩存區(qū);
  • 接著在內(nèi)核空間開(kāi)辟一塊內(nèi)核緩存區(qū)恳谎,建立內(nèi)核緩存區(qū)內(nèi)核中數(shù)據(jù)接收緩存區(qū)之間的映射關(guān)系芝此,以及內(nèi)核中數(shù)據(jù)接收緩存區(qū)接收進(jìn)程用戶(hù)空間地址的映射關(guān)系憋肖;
  • 發(fā)送方進(jìn)程通過(guò)系統(tǒng)調(diào)用 copy_from_user() 將數(shù)據(jù) copy 到內(nèi)核中的內(nèi)核緩存區(qū),由于內(nèi)核緩存區(qū)和接收進(jìn)程的用戶(hù)空間存在內(nèi)存映射婚苹,因此也就相當(dāng)于把數(shù)據(jù)發(fā)送到了接收進(jìn)程的用戶(hù)空間岸更,這樣便完成了一次進(jìn)程間的通信。
BinderIPC原理

Binder 通信模型

Binder通信采用C/S架構(gòu)膊升,從組件視角來(lái)說(shuō)坐慰,包含Client、Server用僧、ServiceManager以及Binder驅(qū)動(dòng)结胀,其中ServiceManager用于管理系統(tǒng)中的各種服務(wù)。其中 Client责循、Server糟港、Service Manager 運(yùn)行在用戶(hù)空間(存疑),Binder 驅(qū)動(dòng)運(yùn)行在內(nèi)核空間院仿。

統(tǒng)觀Binder中的各個(gè)組成元素秸抚,發(fā)現(xiàn)它和TCP/IP網(wǎng)絡(luò)又很多相同之處。

  • Binder驅(qū)動(dòng)——路由器歹垫;
  • Service Manager ——DNS;
  • Binder Client ——客戶(hù)端剥汤;
  • Binder Server —— 服務(wù)端;

TCP/IP一個(gè)典型的連接過(guò)程

TCP/IP一個(gè)典型的連接過(guò)程

client和server建立連接通常有以下幾個(gè)步驟:

  • Client向DNS查詢(xún)Google.com的IP地址排惨。

    首先Client要知道DNS的IP地址才可以吭敢,這個(gè)是在Client接入網(wǎng)絡(luò)之前就完成的。

    如果Client已經(jīng)知道了Server的IP自然可以跳過(guò)這一個(gè)步驟直接與Server連接暮芭。比如windows下提供了一個(gè)hosts文件用于查詢(xún)常用域名與IP的對(duì)應(yīng)關(guān)系鹿驼。

  • DNS將查詢(xún)到的結(jié)果返回給Client。

  • Client得知Googlde.com的IP后辕宏,向Google服務(wù)器發(fā)起連接畜晰。

  • 在這一系列流程中沒(méi)有談到Router,因?yàn)樗淖饔镁褪菍?shù)據(jù)包投遞給目標(biāo)IP瑞筐。

在以上整個(gè)TCP/IP的模型中凄鼻,IP地址是彼此間溝通的唯一憑證。其次Router是構(gòu)建一個(gè)通信網(wǎng)絡(luò)的基礎(chǔ)聚假,它根據(jù)用戶(hù)的目標(biāo)IP來(lái)把數(shù)據(jù)包正確的送達(dá)块蚌。最后DNS不是必須的。

類(lèi)比下 Binder的流程:

進(jìn)程1(客戶(hù)端)想要和進(jìn)程2(服務(wù)端)進(jìn)行訪問(wèn)魔策,因?yàn)樗麄冎g是 跨進(jìn)程的(跨網(wǎng)絡(luò))所以需要Binder驅(qū)動(dòng)(Router)來(lái)把請(qǐng)求正確的投遞到對(duì)方所在的進(jìn)程(服務(wù)端)中匈子,而參與通信的進(jìn)程都需要持有Binder"頒發(fā)"的唯一標(biāo)志(IP地址)。同樣的Binder中的ServiceManager(DNS)也不是必須的闯袒,前提是Client能記住進(jìn)程的Binder標(biāo)志(IP地址)虎敦。特別注意的是這個(gè)Binder標(biāo)志是”動(dòng)態(tài)IP“游岳,意味這每次訪問(wèn)都需要重新獲取,而DNS可以完美的解決這個(gè)問(wèn)題其徙,用于管理Binder標(biāo)志和域名之間的對(duì)應(yīng)關(guān)系胚迫。

DNS有自己的IP地址,那么ServiceManager在Binder的通信過(guò)程的唯一標(biāo)志永遠(yuǎn)是0唾那。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末访锻,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子闹获,更是在濱河造成了極大的恐慌期犬,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件避诽,死亡現(xiàn)場(chǎng)離奇詭異龟虎,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)沙庐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門(mén)鲤妥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人拱雏,你說(shuō)我怎么就攤上這事棉安。” “怎么了铸抑?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵贡耽,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我羡滑,道長(zhǎng)菇爪,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任柒昏,我火速辦了婚禮,結(jié)果婚禮上熙揍,老公的妹妹穿的比我還像新娘职祷。我一直安慰自己,他們只是感情好届囚,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布有梆。 她就那樣靜靜地躺著,像睡著了一般意系。 火紅的嫁衣襯著肌膚如雪泥耀。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,730評(píng)論 1 289
  • 那天蛔添,我揣著相機(jī)與錄音痰催,去河邊找鬼兜辞。 笑死,一個(gè)胖子當(dāng)著我的面吹牛夸溶,可吹牛的內(nèi)容都是我干的逸吵。 我是一名探鬼主播,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼缝裁,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼扫皱!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起捷绑,我...
    開(kāi)封第一講書(shū)人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤韩脑,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后粹污,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體扰才,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年厕怜,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了衩匣。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡粥航,死狀恐怖琅捏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情递雀,我是刑警寧澤柄延,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站缀程,受9級(jí)特大地震影響搜吧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜杨凑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一滤奈、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧撩满,春花似錦蜒程、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至伪嫁,卻和暖如春领炫,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背张咳。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工帝洪, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留似舵,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓碟狞,卻偏偏與公主長(zhǎng)得像啄枕,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子族沃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容