Android Binder 進(jìn)程間通信簡(jiǎn)單理解(無(wú)源碼解析)

為了加深對(duì)android中binder進(jìn)程間通訊流程的記憶草冈,這里記錄一下自己對(duì)binder的理解思路勃黍。

首先Android中binder的進(jìn)程間通訊其實(shí)可以類比java中線程間的通訊器虾,只不過(guò)binder的進(jìn)程間通訊多了一些約束而已阱飘。具體流程看下面屏镊;

與線程間通信類比

假設(shè)現(xiàn)在有線程Thread1和線程Thread2需要通訊针史,Thread1需要把一個(gè)數(shù)據(jù)data傳遞給Thread2那最簡(jiǎn)單的方法就是利用一個(gè)靜態(tài)變量做一下中轉(zhuǎn),這里就把這個(gè)靜態(tài)變量定為MiddleWare.temp赋访,那具體流程就可以用下面這段偽代碼來(lái)表示可都;

MiddleWare.temp = thread1.data;
thread2.data = MiddleWare.temp;

那么再進(jìn)行如下類比

  • MiddleWare類比Binder驅(qū)動(dòng)(Binder驅(qū)動(dòng)可以簡(jiǎn)單的理解成內(nèi)核中的一個(gè)應(yīng)用)
  • Thread1類比進(jìn)程1
  • Thread2類比進(jìn)程2

那上面?zhèn)未a中的兩個(gè)流程就是Binder驅(qū)動(dòng)進(jìn)程間通信的核心邏輯了,是不是很簡(jiǎn)單蚓耽∏總結(jié)一下Binder的作用就是暫存一下數(shù)據(jù)并且交給另一方;

mmap的理解

Binder和其它進(jìn)程間通訊手段有一個(gè)不同就是Binder可以實(shí)現(xiàn)一次copy來(lái)完成數(shù)據(jù)通信步悠,這里繼續(xù)通過(guò)上面那個(gè)類比來(lái)說(shuō)明一下mmap的原理签杈;

普通跨進(jìn)程通信兩次拷貝方案

上面的例子中通過(guò)類比了解了Binder(也就是例子中的MiddleWare)的角色,說(shuō)白了其實(shí)就是一個(gè)中轉(zhuǎn)站鼎兽,而Thread1Thread2則是真正通信的對(duì)象答姥。但是這里類比中有一個(gè)關(guān)鍵的地方線程和進(jìn)程是不同的;就是進(jìn)程之間的內(nèi)存是不共享的谚咬;

這里先補(bǔ)充2個(gè)背景知識(shí):

  1. Linux內(nèi)存分布:Linux內(nèi)存分為內(nèi)核區(qū)用戶區(qū)的踢涌,我們一般的進(jìn)程(如app應(yīng)用)都是跑在用戶區(qū)的,而一些系統(tǒng)進(jìn)程(如Binder驅(qū)動(dòng))則是跑在內(nèi)核區(qū)的序宦;
  2. 內(nèi)核區(qū)和用戶區(qū)區(qū)別:這里只要明白內(nèi)核區(qū)是可以訪問(wèn)(通過(guò)Copy)用戶區(qū)的數(shù)據(jù)睁壁,用戶區(qū)是無(wú)法訪問(wèn)內(nèi)核區(qū)的數(shù)據(jù)就可以了;當(dāng)然用戶區(qū)的不同進(jìn)程自然不可以互相訪問(wèn)數(shù)據(jù)互捌,不然要搞出一個(gè)Binder有啥用潘明;

這里對(duì)內(nèi)核區(qū)用戶區(qū)做一個(gè)簡(jiǎn)單的總結(jié):Binder所在的內(nèi)存區(qū)域權(quán)限最高,Binder可以拿到進(jìn)程1的數(shù)據(jù)也可以拿到進(jìn)程2的數(shù)據(jù)秕噪,同理也可以把數(shù)據(jù)給進(jìn)程1和進(jìn)程2钳降,而進(jìn)程1和進(jìn)程2拿不到Binder所在內(nèi)存的數(shù)據(jù),進(jìn)程1和進(jìn)程2的數(shù)據(jù)是互相不共享的腌巾;

繼續(xù)上面用線程來(lái)類比遂填,那現(xiàn)在的情況就是這樣的:

  • MiddleWare獨(dú)自在一個(gè)線程;
  • Thread1在自己的線程1澈蝙;
  • Thread2在自己的線程2吓坚;
  • MiddleWare需要通過(guò)數(shù)據(jù)Copy來(lái)獲取或賦予Thread1``Thread2的數(shù)據(jù)

那具體流程就變成了下面這段偽代碼:

MiddleWare.temp.copyFrom(thread1.data);
MiddleWare.temp.copyTo(thread2.data);

這里就是一般的跨進(jìn)程通信的核心流程了,而從上面分析可以看出一般跨進(jìn)程通信需要對(duì)數(shù)據(jù)進(jìn)行兩次Copy

mmap數(shù)據(jù)的一次拷貝

Android為什么用Binder作為跨進(jìn)程通信的手段自然是因?yàn)锽inder的高性能了灯荧,Binder通過(guò)mmap來(lái)將兩次Copy優(yōu)化至一次Copy礁击;

mmap是什么?mmap的全稱為MemoryMap也就是內(nèi)存映射,簡(jiǎn)單的說(shuō)可以把內(nèi)核區(qū)也就是Binder所在的內(nèi)存空間中的內(nèi)存映射到用戶區(qū)哆窿,這樣用戶區(qū)拿這部分?jǐn)?shù)據(jù)就可以不用Copy了链烈。

mmap既然可以直接映射內(nèi)存把內(nèi)核區(qū)的映射到用戶區(qū)那假如按照如下方案:


mmap_error.png

如圖按照上圖的做法是不是只要兩次映射,都不需要Copy就完成數(shù)據(jù)的傳輸也就是跨進(jìn)程的通訊了挚躯?這里我一開(kāi)始也是這樣想的强衡,但事實(shí)不是這樣的;

這里有一點(diǎn)需要注意码荔,就是mmap內(nèi)存映射后漩勤,用戶區(qū)的數(shù)據(jù)要到內(nèi)核區(qū)還是需要通過(guò)Copy才能完成的,而用戶區(qū)獲取數(shù)據(jù)則可以直接通過(guò)mmap內(nèi)存映射讀取內(nèi)核區(qū)的數(shù)據(jù)目胡,不再需要再經(jīng)過(guò)Copy(好像還需要一次淺拷貝,替換一下內(nèi)核區(qū)的引用链快?)

那繼續(xù)就上面這個(gè)類比的例子目前經(jīng)過(guò)mmap優(yōu)化過(guò)以后的偽代碼就是這樣的:

//把Thread1的數(shù)據(jù) 從用戶區(qū)Copy到 Thread2在MiddleWare中
//的映射區(qū)域MiddleWare.thread2MapData中去
MiddleWare.thread2MapData.copyFrom(thread1.data);

//Thread2通過(guò)mmap內(nèi)存映射獲取對(duì)應(yīng)映射區(qū)
//域MiddleWare.thread2MapData的數(shù)據(jù)
thread2.data = MiddleWare.thread2MapData;

這里再附上一個(gè)圖幫助理解


binder_mmp.png

(Thread MiddleWare的類比關(guān)系應(yīng)該不用在說(shuō)了吧)

這里就可以清楚的看到Binder中mmap是怎么通過(guò)一次Copy來(lái)完成數(shù)據(jù)的傳輸?shù)模?br> 至于Binder的C/S架構(gòu)誰(shuí)是Client誰(shuí)是Server誉己,在當(dāng)前的例子中自然是Thread1(進(jìn)程1)是Client,Thread2(進(jìn)程2)是服務(wù)端了域蜗。當(dāng)然這個(gè)角色都是會(huì)發(fā)生變化的巨双,比如Thread1發(fā)送數(shù)據(jù)后Thread2處理完數(shù)據(jù)要把結(jié)果返回給Thread1,那此時(shí)Thread2就是Client端霉祸,Thread1就是Server端了筑累。這里不變的依據(jù)就是誰(shuí)接受數(shù)據(jù)并且處理數(shù)據(jù)誰(shuí)就是Server端,誰(shuí)發(fā)送數(shù)據(jù)誰(shuí)就是Client端丝蹭;

上面就是我自己對(duì)Binder通信流程的一部分理解和總結(jié)了慢宗,通過(guò)線程間通訊來(lái)類比也是為了方便記憶。當(dāng)然這里還沒(méi)有完奔穿,這里還有幾個(gè)疑問(wèn):

  1. 進(jìn)程1是如何找到進(jìn)程2的镜沽,或者說(shuō)找到進(jìn)程2在內(nèi)核區(qū)映射的內(nèi)存地址?
  2. 相對(duì)于Native層Framework層Binder的架構(gòu)又是怎樣的贱田?
  3. Binder看起來(lái)很虛缅茉,那我們平時(shí)要怎么用Binder這個(gè)東西?(AIDL男摧?它的實(shí)質(zhì)是什么)

上面這些疑問(wèn)我后面會(huì)陸續(xù)整理的蔬墩,至于BpBinder、BBinder耗拓、BinderProxy拇颅、IBinder這些亂七八糟的也都是為了完成這個(gè)架構(gòu)而提出的,有時(shí)間會(huì)再整理說(shuō)明乔询。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蔬蕊,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌岸夯,老刑警劉巖麻献,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異猜扮,居然都是意外死亡勉吻,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門旅赢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)齿桃,“玉大人,你說(shuō)我怎么就攤上這事煮盼《套荩” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵僵控,是天一觀的道長(zhǎng)香到。 經(jīng)常有香客問(wèn)我,道長(zhǎng)报破,這世上最難降的妖魔是什么悠就? 我笑而不...
    開(kāi)封第一講書人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮充易,結(jié)果婚禮上梗脾,老公的妹妹穿的比我還像新娘。我一直安慰自己盹靴,他們只是感情好炸茧,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著稿静,像睡著了一般宇立。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上自赔,一...
    開(kāi)封第一講書人閱讀 49,929評(píng)論 1 290
  • 那天妈嘹,我揣著相機(jī)與錄音,去河邊找鬼绍妨。 笑死润脸,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的他去。 我是一名探鬼主播毙驯,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼灾测!你這毒婦竟也來(lái)了爆价?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎铭段,沒(méi)想到半個(gè)月后骤宣,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡序愚,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年憔披,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片爸吮。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡芬膝,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出形娇,到底是詐尸還是另有隱情锰霜,我是刑警寧澤,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布桐早,位于F島的核電站癣缅,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏勘畔。R本人自食惡果不足惜所灸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一丽惶、第九天 我趴在偏房一處隱蔽的房頂上張望炫七。 院中可真熱鬧,春花似錦钾唬、人聲如沸万哪。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)奕巍。三九已至,卻和暖如春儒士,著一層夾襖步出監(jiān)牢的瞬間的止,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工着撩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留诅福,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓拖叙,卻偏偏與公主長(zhǎng)得像氓润,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子薯鳍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350

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