僅做個(gè)人學(xué)習(xí)記錄
什么是IPC?
inter-process-communication 進(jìn)程間通信(跨進(jìn)程通信)侧巨,兩個(gè)進(jìn)程間進(jìn)行數(shù)據(jù)交互的過(guò)程惨远。
什么是線程易阳?什么是進(jìn)程附较??jī)烧叩年P(guān)系?
線程:是CUP調(diào)度的最小單元潦俺,同時(shí)是一種有限的系統(tǒng)資源。
進(jìn)程:一般指一個(gè)執(zhí)行單元徐勃,在PC或移動(dòng)設(shè)備上表示為一個(gè)程序或者應(yīng)用事示。
一個(gè)進(jìn)程中可以包含過(guò)個(gè)線程,一個(gè)或多個(gè)線程系統(tǒng)的組成就是一個(gè)程序僻肖。
IPC是Android獨(dú)有的嗎肖爵?Linux有那些跨進(jìn)程通信?
任何一個(gè)操作系統(tǒng)都需要一套IPC通信機(jī)制臀脏,比如windows的剪切板劝堪、管道...
linux的跨進(jìn)程通信方式:
- 命名管道
- 消息隊(duì)列
- 共享內(nèi)存
- 套接字冀自、信號(hào)量、信號(hào)
Android有哪些跨進(jìn)程通信方式秒啦?
- Binder
- Bundle
- 文件共享
- AIDL
- Messenger
- ContentProvider
- Socket
Android是基于Linux內(nèi)核開發(fā)的操作系統(tǒng)熬粗,為什么不采用Linux的IPC通信方式?
管道:緩存區(qū)容量有限余境,不適合Android大量的進(jìn)程間通信需求驻呐。
消息隊(duì)列:和命名管道一樣每次數(shù)據(jù)快的容量有限制;消息復(fù)制兩次(用戶空間到內(nèi)存芳来,內(nèi)存到用戶空間)含末,額外消耗cpu,不適合Android頻繁的通信要求即舌。
共享內(nèi)存:共享內(nèi)存就是允許兩個(gè)不相關(guān)的進(jìn)程訪問(wèn)同一個(gè)邏輯內(nèi)存佣盒。 共享內(nèi)存是在兩個(gè)正在運(yùn)行的進(jìn)程之間共享和傳遞數(shù)據(jù)的一種非常有效 的方式。不同進(jìn)程之間共享的內(nèi)存通常安排為同一段物理內(nèi)存顽聂。進(jìn)程可以 將同一段共享內(nèi)存連接到它們自己的地址空間中肥惭,所有進(jìn)程都可以訪問(wèn)共 享內(nèi)存中的地址。
無(wú)需復(fù)制芜飘,共享緩沖區(qū)务豺,速度快。但是安全問(wèn)題比較突出嗦明。
套接字:效率太低笼沥,主要用來(lái)跨網(wǎng)絡(luò)通信。
信號(hào)量:常作為一種鎖機(jī)制娶牌,防止某進(jìn)程正在訪問(wèn)共享資源時(shí)奔浅,其他進(jìn)程也訪問(wèn)該資源。因此诗良,主要作為進(jìn)程間以及同一進(jìn)程內(nèi)不同線程之間的同步手段汹桦。
信號(hào):不適用于信息交換,更適用于進(jìn)程中斷控制鉴裹,比如非法內(nèi)存訪問(wèn)舞骆,殺死某個(gè)進(jìn)程等;
Binder:Binder驅(qū)動(dòng)會(huì)在
為何會(huì)選Binder:
- 傳遞性:Binder數(shù)據(jù)需要進(jìn)行一次拷貝径荔,而共享內(nèi)存完全不需要進(jìn)行數(shù)據(jù)拷貝督禽。
- 穩(wěn)定性:Binder采用CS的架構(gòu)方式,Server端和Client端相對(duì)獨(dú)立总处,穩(wěn)定性好狈惫。共享內(nèi)存需要充分考慮臨界資源的訪問(wèn)問(wèn)題,很容易出現(xiàn)死鎖問(wèn)題鹦马。
- 安全性:Android端會(huì)為每個(gè)已安裝的應(yīng)用程序分配一個(gè)UID胧谈,Binder只對(duì)外暴露Client端忆肾,Client端會(huì)將任務(wù)發(fā)送給Server端,Server端會(huì)根據(jù)權(quán)限控制策略對(duì)UID進(jìn)行甄別是否滿足訪問(wèn)權(quán)限菱肖。
- 其他原因:Linux是受GPL保護(hù)的客冈。
傳統(tǒng)的IPC只能由用戶在數(shù)據(jù)包里填寫ID;傳統(tǒng)IPC接入點(diǎn)也是開放的蔑滓,無(wú)法建立私有通道郊酒。
- 臨界資源:多進(jìn)程系統(tǒng)中,它們共享各種資源键袱,然而有很多資源一次只能供一個(gè)進(jìn)程使用燎窘。一次僅允許一個(gè)進(jìn)程使用的資源稱為臨界資源。許多物理設(shè)備都屬于臨界資源蹄咖,如輸入機(jī)褐健、打印機(jī)、磁帶機(jī)等澜汤。
- GPL:是GNU General Public License的縮寫蚜迅。例如,如果你發(fā)布一個(gè)程序的副本俊抵,不管是收費(fèi)的還是免費(fèi)的谁不,你必須將你具有的一切權(quán)利給予你的接受者;你必須保證他們能收到或得到源程序徽诲;并且將這些條款給他們看刹帕,使他們知道他們有這樣的權(quán)利。
- Binder是基于開源的OpenBinder實(shí)現(xiàn)的谎替。
傳統(tǒng)的IPC就沒(méi)有在Android中用到嗎偷溺?
比如在 Android OS 中的 Zygote 進(jìn)程的 IPC 采用的是 Socket(套 接字)機(jī)制,Android 中的 Kill Process 采用的 signa(l 信號(hào))機(jī)制等等钱贯。而 Binder 更多則用在 system_server 進(jìn)程與上層 App 層的 IPC 交互挫掏。
開發(fā)中有哪些多進(jìn)程的情況?
- 需要加大一個(gè)應(yīng)用的可使用內(nèi)存秩命,通過(guò)多進(jìn)程獲取多份內(nèi)存尉共。
- 需要將其他模塊運(yùn)行在獨(dú)立進(jìn)程當(dāng)中,比如進(jìn)程逼瘢活爸邢。
- 需要和其他應(yīng)用通信,相互獲取數(shù)據(jù)拿愧。
如何開啟多進(jìn)程模式?
- 給四大組件設(shè)置android.process屬性
- 通過(guò)JNI在native層去孵化一個(gè)進(jìn)程
<activity
android:name="com.ipc.app.page"/>
<activity
android:process=":test"
android:name="com.ipc.app.page1"/>
<activity
android:process="com.ipc.app.test"
android:name="com.ipc.app.page2" />
page會(huì)運(yùn)行在默認(rèn)的進(jìn)程(com.ipc.app)當(dāng)中碌尔;
page1會(huì)運(yùn)行在com.ipc.app:test進(jìn)程當(dāng)中浇辜;
page2會(huì)運(yùn)行在com.ipc.app.test進(jìn)程當(dāng)中券敌;
page1和page2不是同一個(gè)進(jìn)程。因?yàn)椤埃骸北硎玖螅且诋?dāng)前進(jìn)程名前添加當(dāng)前包名待诅,這是一種簡(jiǎn)寫,并且以“:”開頭的進(jìn)程為當(dāng)前應(yīng)用的私有進(jìn)程熊镣,其他應(yīng)用的組件不可以和他跑在同一個(gè)進(jìn)程當(dāng)中卑雁。
反之不以“:”開頭則為全局進(jìn)程,其他應(yīng)用通過(guò)ShareUID方式可以和他跑在同一個(gè)進(jìn)程。
使用多進(jìn)程會(huì)有哪些問(wèn)題绪囱?
- 靜態(tài)成員和單列模式失效
- 線程同步機(jī)制失效
- sharedPreferences可靠性變差
- application多次創(chuàng)建
解釋:Android會(huì)為每個(gè)進(jìn)程分配一個(gè)獨(dú)立的虛擬機(jī)测蹲,不同的虛擬機(jī)就會(huì)有不同的地址控件,不同的虛擬機(jī)訪問(wèn)同一個(gè)對(duì)象就會(huì)產(chǎn)生不同的副本鬼吵,并且互不干擾扣甲,這樣就會(huì)出現(xiàn)第一種和第二種情況。SharedPreferences雖然是線程安全的齿椅,但是不支持多進(jìn)程操作琉挖,可能會(huì)導(dǎo)致數(shù)據(jù)的丟失。開啟一個(gè)新的進(jìn)程涣脚,就是開啟一個(gè)新的應(yīng)用示辈,當(dāng)然會(huì)創(chuàng)建application。
Binder是什么遣蚀?
- 從IPC的角度來(lái)說(shuō)矾麻,它是Android中的一種跨進(jìn)程通信的方式,Linux系統(tǒng)中沒(méi)有這種通信方式妙同。
- 從FrameWork角度來(lái)說(shuō)射富,Binder是ServiceManager鏈接各種Manger(ActivityManger、WindowManger...)和相應(yīng)MangerService的橋梁粥帚。
- 從Application層來(lái)說(shuō)胰耗,Binder是客戶端和服務(wù)端進(jìn)行通信的媒介,bindService時(shí)候芒涡,服務(wù)端會(huì)返回一個(gè)帶有服務(wù)端業(yè)務(wù)嗲用的Binder對(duì)象柴灯,通過(guò)這個(gè)Binder對(duì)象,客戶端可以獲取服務(wù)端提供的服務(wù)或者數(shù)據(jù)费尽,這里的服務(wù)包含普通服務(wù)和基于AIDL的服務(wù)赠群。
Binder的工作流程?
Binder通信有四個(gè)很重要的角色:
- Binder驅(qū)動(dòng):運(yùn)行在內(nèi)核控件旱幼,負(fù)責(zé)各個(gè)用戶進(jìn)程通過(guò)Binder實(shí)現(xiàn)通信的內(nèi)核模塊查描。
- ServiceManger
- BinderClient
- BinderServer
舉個(gè)例子:
1.從上海回西安,需要把行李快遞回家
2.忘了家里的詳細(xì)地址冬三,通過(guò)備忘錄找到家里的地址
3.將行李放入蜂巢匀油,快遞會(huì)把行李從蜂巢運(yùn)送到家
這樣就完成了一次Binder通信,其中上海(BinderClient)勾笆,西安的家(BinderServer)敌蚜、備忘錄(serviceManger)、蜂巢物流系統(tǒng)(Binder驅(qū)動(dòng))窝爪。
操作系統(tǒng)采用虛擬存儲(chǔ)器弛车,在邏輯上將虛擬空間分為內(nèi)核空間和用戶空間,為了保證安全安全性他們之間是隔離的蒲每。用戶是不能直接操作內(nèi)核的纷跛,但不可避免的用戶空間需要訪問(wèn)內(nèi)核(文件操作,網(wǎng)絡(luò)訪問(wèn))啃勉,為了突破這層隔離就需要進(jìn)行系統(tǒng)調(diào)用忽舟。
- 內(nèi)核空間:系統(tǒng)內(nèi)核運(yùn)行的空間
- 用戶空間:用戶程序運(yùn)行的空間
- 系統(tǒng)調(diào)用是用戶訪問(wèn)內(nèi)核的唯一途徑,保證了內(nèi)核資源的訪問(wèn)都是在內(nèi)核的監(jiān)控下完成的淮阐,防止了用戶空間的越權(quán)訪問(wèn)叮阅,提升了系統(tǒng)的安全性和穩(wěn)定性。
系統(tǒng)調(diào)用步驟:
1.將數(shù)據(jù)從用戶空間拷貝到內(nèi)核空間
2.將數(shù)據(jù)從內(nèi)核空間拷貝到用戶空間
- 消息發(fā)送方將消息放入自行開辟的內(nèi)存緩存區(qū)中
- 通過(guò)系統(tǒng)調(diào)用進(jìn)入內(nèi)核運(yùn)行態(tài)(內(nèi)核態(tài))
- 內(nèi)核程序開辟一塊內(nèi)核緩存區(qū)泣特,將數(shù)據(jù)從消息發(fā)送方的內(nèi)存緩存區(qū)中拷貝過(guò)來(lái)浩姥。
- 內(nèi)核程序處理完畢后,消息接收方從內(nèi)核緩存區(qū)中將數(shù)據(jù)拷貝到自己的內(nèi)存緩存區(qū)中状您。
傳統(tǒng)通信存在的問(wèn)題:
- 需要盡量?jī)纱螖?shù)據(jù)拷貝勒叠,效率低下。
- 接收方并不知道數(shù)據(jù)有多大膏孟,會(huì)開辟很大的內(nèi)存緩存區(qū)來(lái)進(jìn)行數(shù)據(jù)接受眯分;或者通過(guò)其他方式先獲取數(shù)據(jù)大小,浪費(fèi)時(shí)間柒桑。
Binder不是系統(tǒng)內(nèi)核的一部分弊决,如何完成進(jìn)程通信?
Linux的動(dòng)態(tài)內(nèi)核可加載模塊的機(jī)制魁淳。