摘要:中為何新增來作為主要的方式運行機制是怎樣的機制有什么優勢運行機制是怎樣的基于通信模式,除了端和端,還有兩角色一起合作完成進程間通信功能。
目錄介紹
2.0.0.1 什么是Binder?為什么要使用Binder?Binder中是如何進行線程管理的?總結binder講的是什么?
2.0.0.2 Android中進程和線程的關系?什么是IPC?為何需要進行IPC?多進程通信可能會出現什么問題?
2.0.0.3 Binder的工作流程是怎樣的?Binder主要能提供哪些功能?Binder通信機制原理是怎樣的?
2.0.0.4 Android中為何新增Binder來作為主要的IPC方式?Binder運行機制是怎樣的?Binder機制有什么優勢?
2.0.0.5 Android中跨進程通訊的幾種方式?實際開發中,有哪些場景使用Binder進行數據傳輸?
2.0.0.6 Android中有哪些基于Binder的IPC方式?簡單對比下?
2.0.0.7 為何說Binder相比傳統的Socket性能更高效?為何說Binder相比傳統IPC安全性更高?
2.0.0.8 Service Manager是如何成為一個守護進程的?Server和Client是如何獲得Service Manager接口的?
好消息博客筆記大匯總【15年10月到至今】,包括Java基礎及深入知識點,Android技術博客,Python學習筆記等等,還包括平時開發中遇到的bug匯總,當然也在工作之余收集了大量的面試題,長期更新維護并且修正,持續完善……開源的文件是markdown格式的!同時也開源了生活博客,從12年起,積累共計500篇[近100萬字],將會陸續發表到網上,轉載請注明出處,謝謝!
鏈接地址:https://github.com/yangchong2...
如果覺得好,可以star一下,謝謝!當然也歡迎提出建議,萬事起于忽微,量變引起質變!所有的筆記將會更新到GitHub上,同時保持更新,歡迎同行提出或者push不同的看法或者筆記!
2.0.0.1 什么是Binder?為什么要使用Binder?Binder中是如何進行線程管理的?總結binder講的是什么?
什么是Binder?
1.直觀來說,Binder是Android中的一個類,它繼承了IBinder接口
2.從IPC角度來說,Binder是Android中的一種跨進程通信方式,Binder還可以理解為一種虛擬的物理設備,它的設備驅動是/dev/binder,該通信方式在linux中沒有
3.從Android Framework角度來說,Binder是ServiceManager連接各種Manager(ActivityManager、WindowManager,etc)和相應ManagerService的橋梁
4.從Android應用層來說,Binder是客戶端和服務端進行通信的媒介,當你bindService的時候,服務端會返回一個包含了服務端業務調用的Binder對象,通過這個Binder對象,客戶端就可以獲取服務端提供的服務或者數據,這里的服務包括普通服務和基于AIDL的服務。
為什么要使用Binder?技術博客大總結
在傳統的Linux上,我們還是有很多選擇可以用來實現進程間通信,如管道、SystemV、Socket等。那么Android為什么不使用這些原有的技術,而是要使開發一種新的叫Binder的進程間通信機制呢?
最簡單的回答:性能:相比傳統的Socket更高效;安全:安全性高,支持通信雙方進行身份驗證。
詳細一點說,主要有兩個方面的原因:
性能方面
在移動設備上(性能受限制的設備,比如要省電),廣泛地使用跨進程通信對通信機制的性能有嚴格的要求,Binder相對出傳統的Socket方式,更加高效。Binder數據拷貝只需要一次,而管道、消息隊列、Socket都需要2次,共享內存方式一次內存拷貝都不需要,但實現方式又比較復雜。
安全方面
傳統的進程通信方式對于通信雙方的身份并沒有做出嚴格的驗證,比如Socket通信ip地址是客戶端手動填入,很容易進行偽造,而Binder機制從協議本身就支持對通信雙方做身份校檢,因而大大提升了安全性。
還有一些好處,如實現面象對象的調用方式,在使用Binder時就和調用一個本地實例一樣。
Binder中是如何進行線程管理的?
每個Binder的Server進程會創建很多線程來處理Binder請求,可以簡單的理解為創建了一個Binder的線程池吧(雖然實際上并不完全是這樣簡單的線程管理方式),而真正管理這些線程并不是由這個Server端來管理的,而是由Binder驅動進行管理的。
一個進程的Binder線程數默認最大是16,超過的請求會被阻塞等待空閑的Binder線程。理解這一點的話,你做進程間通信時處理并發問題就會有一個底,比如使用ContentProvider時(又一個使用Binder機制的組件),你就很清楚它的CRUD(創建、檢索、更新和刪除)方法只能同時有16個線程在跑。
總結binder講的是什么?
通常意義上來說,Binder就是指Andriod的通信機制;
對于服務端進程來說,Binder指的是Binder本地對象,對于客戶端進程來說,Binder指的是Binder代理對象。
對于傳輸過程來說,Binder是可以進行跨進程傳遞的對象;
2.0.0.2 Android中進程和線程的關系?什么是IPC?為何需要進行IPC?多進程通信可能會出現什么問題?
Android中進程和線程的關系?
一個APP一般對應一個進程和有限個線程
一般對應一個進程,當然,可以在AndroidMenifest中給四大組件指定屬性android:process開啟多進程模式
有限個線程:線程是一種受限的系統資源,不可無限制的產生且線程的創建和銷毀都有一定的開銷。
什么是IPC?
為何需要進行IPC?
進程間通信的必要性
所有運行在不同進程的四大組件,只要它們之間需要通過內存在共享數據,都會共享失敗。這是由于Android為每個應用分配了獨立的虛擬機,不同的虛擬機在內存分配上有不同的地址空間,這會導致在不同的虛擬機中訪問同一個類的對象會產生多份副本。技術博客大總結
多進程造成的影響可總結為以下四方面
靜態變量和單例模式失效:由獨立的虛擬機造成
線程同步機制失效:由獨立的虛擬機造成
SharedPreference的不可靠下降:不支持兩個進程同時進行讀寫操作,即不支持并發讀寫,有一定幾率導致數據丟失
Application多次創建:Android系統會為新的進程分配獨立虛擬機,相當于系統又把這個應用重新啟動了一次。
2.0.0.3 Binder的工作流程是怎樣的?Binder主要能提供哪些功能?Binder通信機制原理是怎樣的?
Binder的工作流程是怎樣的?
1客戶端首先獲取服務器端的代理對象。所謂的代理對象實際上就是在客戶端建立一個服務端的“引用”,該代理對象具有服務端的功能,使其在客戶端訪問服務端的方法就像訪問本地方法一樣。
2客戶端通過調用服務器代理對象的方式向服務器端發送請求。
3代理對象將用戶請求通過Binder驅動發送到服務器進程。
4服務器進程處理用戶請求,并通過Binder驅動返回處理結果給客戶端的服務器代理對象。
5客戶端收到服務端的返回結果。
binder工作流程圖如下所示:
Binder主要能提供哪些功能?
用驅動程序來推進進程間的通信。
通過共享內存來提高性能。
為進程請求分配每個進程的線程池。
針對系統中的對象引入了引用計數和跨進程的對象引用映射。
進程間同步調用。
Binder通信機制原理是怎樣的?
Server進程向ServiceManager注冊,告訴ServiceManager我是誰,我有什么,我能做什么。就好比徐同學(Server進程)有一臺筆記本(computer對象),這臺筆記本有個add方法。這時映射關系表就生成了。技術博客大總結
Client進程向ServiceManager查詢,我要調用Server進程的computer對象的add方法,可以看到這個過程經過Binder驅動,這時候Binder驅動就開始發揮他的作用了。當向ServiceManager查詢完畢,是返回一個computer對象給Client進程嗎?其實不然,Binder驅動將computer對象轉換成了computerProxy對象,并轉發給了Client進程,因此,Client進程拿到的并不是真實的computer對象,而是一個代理對象,即computerProxy對象。很容易理解這個computerProxy對象也是有add方法,(如果連add方法都沒有,豈不是欺騙了Client?),但是這個add方法只是對參數進行一些包裝而已。
當Client進程調用add方法,這個消息發送給Binder驅動,這時驅動發現,原來是computerProxy,那么Client進程應該是需要調用computer對象的add方法的,這時驅動通知Server進程,調用你的computer對象的add方法,將結果給我。然后Server進程就將計算結果發送給驅動,驅動再轉發給Client進程,這時Client進程還蒙在了鼓里,他以為自己調用的是真實的computer對象的add方法,其實他只是調用了代理而已。不過Client最終還是拿到了計算結果。
2.0.0.4 Android中為何新增Binder來作為主要的IPC方式?Binder運行機制是怎樣的?Binder機制有什么優勢?
Binder運行機制是怎樣的?
Binder基于Client-Server通信模式,除了Client端和Server端,還有兩角色一起合作完成進程間通信功能。
Binder通信的四個角色:
Client進程:使用服務的進程。
Server進程:提供服務的進程。
ServiceManager進程:ServiceManager的作用是將字符形式的Binder名字轉化成Client中對該Binder的引用,使得Client能夠通過Binder名字獲得對Server中Binder實體的引用。
Binder驅動:驅動負責進程之間Binder通信的建立,Binder在進程之間的傳遞,Binder引用計數管理,數據包在進程之間的傳遞和交互等一系列底層支持。
接觸這些概念可能會覺得難于理解,讀者可以把四個角色和熟悉的互聯網進行類比:Server是服務器,Client是客戶終端,ServiceManager是域名服務器(DNS),驅動是路由器。
Binder機制有什么優勢
傳輸效率高、可操作性強:傳輸效率主要影響因素是內存拷貝的次數,拷貝次數越少,傳輸速率越高。從Android進程架構角度分析:對于消息隊列、Socket和管道來說,數據先從發送方的緩存區拷貝到內核開辟的緩存區中,再從內核緩存區拷貝到接收方的緩存區,一共兩次拷貝
技術博客大總結
對于Binder來說,數據從發送方的緩存區拷貝到內核的緩存區,而接收方的緩存區與內核的緩存區是映射到同一塊物理地址的,節省了一次數據拷貝的過程
由于共享內存操作復雜,綜合來看,Binder的傳輸效率是最好的。
實現C/S架構方便:Linux的眾IPC方式除了Socket以外都不是基于C/S架構,而Socket主要用于網絡間的通信且傳輸效率較低。Binder基于C/S架構 ,Server端與Client端相對獨立,穩定性較好。
安全性高:傳統Linux IPC的接收方無法獲得對方進程可靠的UID/PID,從而無法鑒別對方身份;而Binder機制為每個進程分配了UID/PID且在Binder通信時會根據UID/PID進行有效性檢測。
2.0.0.5 Android中跨進程通訊的幾種方式?實際開發中,有哪些場景使用Binder進行數據傳輸?
Android中跨進程通訊的幾種方式?
Android 跨進程通信,像intent,contentProvider,廣播,service都可以跨進程通信。
intent:這種跨進程方式并不是訪問內存的形式,它需要傳遞一個uri,比如說打電話。
contentProvider:這種形式,是使用數據共享的形式進行數據共享。
service:遠程服務,aidl
廣播技術博客大總結
實際開發中,有哪些場景使用Binder進行數據傳輸?
通過AIDL實現方式解釋Binder數據傳輸的具體過程
服務端中的Service給與其綁定的客戶端提供Binder對象,客戶端通過AIDL接口中的asInterface()將這個Binder對象轉換為代理Proxy,并通過它發起RPC請求。客戶端發起請求時會掛起當前線程,并將參數寫入data然后調用transact(),RPC請求會通過系統底層封裝后由服務端的onTransact()處理,并將結果寫入reply,最后返回調用結果并喚醒客戶端線程。
AIDL原理是什么?如何優化多模塊都使用AIDL的情況?
AIDL(Android Interface Definition Language,Android接口定義語言):如果在一個進程中要調用另一個進程中對象的方法,可使用AIDL生成可序列化的參數,AIDL會生成一個服務端對象的代理類,通過它客戶端實現間接調用服務端對象的方法。
AIDL的本質是系統提供了一套可快速實現Binder的工具。關鍵類和方法:
AIDL接口:繼承IInterface。 Stub類:Binder的實現類,服務端通過這個類來提供服務。 Proxy類:服務器的本地代理,客戶端通過這個類調用服務器的方法。 asInterface():客戶端調用,將服務端的返回的Binder對象,轉換成客戶端所需要的AIDL接口類型對象。返回對象: 若客戶端和服務端位于同一進程,則直接返回Stub對象本身; 否則,返回的是系統封裝后的Stub.proxy對象。 asBinder():根據當前調用情況返回代理Proxy的Binder對象。 onTransact():運行服務端的Binder線程池中,當客戶端發起跨進程請求時,遠程請求會通過系統底層封裝后交由此方法來處理。 transact():運行在客戶端,當客戶端發起遠程請求的同時將當前線程掛起。之后調用服務端的onTransact()直到遠程請求返回,當前線程才繼續執行。
當有多個業務模塊都需要AIDL來進行IPC,此時需要為每個模塊創建特定的aidl文件,那么相應的Service就會很多。必然會現系統資源耗費嚴重、應用過度重量級的問題。解決辦法是建立Binder連接池,即將每個業務模塊的Binder請求統一轉發到一個遠Service中去執行,從而避免重復創建Service。
工作原理:每個業務模塊創建自己的AIDL接口并實現此接口,然后向服務端提供自己的唯一標識和其對應的Binder對象。服務端只需要一個Service,服務器提供一個queryBinder接口,它會根據業務模塊的特征來返回相應的Binder對像,不同的業務模塊拿到所需的Binder對象后就可進行遠程方法的調用了。
2.0.0.6 Android中有哪些基于Binder的IPC方式?簡單對比下? 2.0.0.7 為何說Binder相比傳統的Socket性能更高效?為何說Binder相比傳統IPC安全性更高?
為何說Binder相比傳統的Socket性能更高效?
跨進程通訊中,只有socket支持Client-Server的通信方式,但是socket作為一款通用接口,其傳輸效率低,開銷大,主要用在跨網絡的進程間通信和本機上進程間的低速通信。
消息隊列和管道采用存儲-轉發方式,即數據先從發送方緩存區拷貝到內核開辟的緩存區中,然后再從內核緩存區拷貝到接收方緩存區,至少有兩次拷貝過程。
共享內存雖然無需拷貝,但控制復雜,難以使用。
為何說Binder相比傳統IPC安全性更高?
首先傳統IPC的接收方無法獲得對方進程可靠的UID和PID(用戶ID進程ID),從而無法鑒別對方身份。Android為每個安裝好的應用程序分配了自己的UID,故進程的UID是鑒別進程身份的重要標志。使用傳統IPC只能由用戶在數據包里填入UID和PID,但這樣不可靠,容易被惡意程序利用。可靠的身份標記只有由IPC機制本身在內核中添加。其次傳統IPC訪問接入點是開放的,無法建立私有通道。比如命名管道的名稱,systemV的鍵值,socket的ip地址或文件名都是開放的,只要知道這些接入點的程序都可以和對端建立連接,不管怎樣都無法阻止惡意程序通過猜測接收方地址獲得連接。
基于以上原因,Android需要建立一套新的IPC機制來滿足系統對通信方式,傳輸性能和安全性的要求,這就是Binder。
Binder基于Client-Server通信模式,傳輸過程只需一次拷貝,為發送發添加UID/PID身份,既支持實名Binder也支持匿名Binder,安全性高。技術博客大總結
2.0.0.8 Service Manager是如何成為一個守護進程的?Server和Client是如何獲得Service Manager接口的?
Service Manager是如何成為一個守護進程的?
Service Manager,它是整個Binder機制的守護進程,用來管理開發者創建的各種Server,并且向Client提供查詢Server遠程接口的功能技術博客大總結
既然Service Manager組件是用來管理Server并且向Client提供查詢Server遠程接口的功能,那么,Service Manager就必然要和Server以及Client進行通信了。我們知道,Service Manger、Client和Server三者分別是運行在獨立的進程當中,這樣它們之間的通信也屬于進程間通信了,而且也是采用Binder機制進行進程間通信,因此,Service Manager在充當Binder機制的守護進程的角色的同時,也在充當Server的角色,然而,它是一種特殊的Server,下面我們將會看到它的特殊之處
Service Manager在用戶空間的源代碼位于frameworks/base/cmds/servicemanager目錄下,主要是由binder.h、binder.c和service_manager.c三個文件組成。Service Manager的入口位于service_manager.c文件中的main函數:
int main(int argc, char **argv){ struct binder_state *bs; void *svcmgr = BINDER_SERVICE_MANAGER; bs = binder_open(128*1024); if (binder_become_context_manager(bs)) { LOGE("cannot become context manager (%s) ", strerror(errno)); return -1; } svcmgr_handle = svcmgr; binder_loop(bs, svcmgr_handler); return 0; }
main函數主要有三個功能:一是打開Binder設備文件;二是告訴Binder驅動程序自己是Binder上下文管理者,即我們前面所說的守護進程;三是進入一個無窮循環,充當Server的角色,等待Client的請求
Server和Client是如何獲得Service Manager接口的?
ServiceManager作為守護進程,Service Manager的職責當然就是為Server和Client服務了。那么,Server和Client如何獲得Service Manager接口,進而享受它提供的服務呢?
Service Manager在Binder機制中既充當守護進程的角色,同時它也充當著Server角色,然而它又與一般的Server不一樣。對于普通的Server來說,Client如果想要獲得Server的遠程接口,那么必須通過Service Manager遠程接口提供的getService接口來獲得,這本身就是一個使用Binder機制來進行進程間通信的過程。而對于Service Manager這個Server來說,Client如果想要獲得Service Manager遠程接口,卻不必通過進程間通信機制來獲得,因為Service Manager遠程接口是一個特殊的Binder引用,它的引用句柄一定是0。
經過一系列的調用...
回到defaultServiceManager函數中,最終結果為:gDefaultServiceManager = new BpServiceManager(new BpBinder(0));
這樣,Service Manager遠程接口就創建完成了,它本質上是一個BpServiceManager,包含了一個句柄值為0的Binder引用。技術博客大總結
在Android系統的Binder機制中,Server和Client拿到這個Service Manager遠程接口之后怎么用呢?
對Server來說,就是調用IServiceManager::addService這個接口來和Binder驅動程序交互了,即調用BpServiceManager::addService 。而BpServiceManager::addService又會調用通過其基類BpRefBase的成員函數remote獲得原先創建的BpBinder實例,接著調用BpBinder::transact成員函數。在BpBinder::transact函數中,又會調用IPCThreadState::transact成員函數,這里就是最終與Binder驅動程序交互的地方了。回憶一下前面的類圖,IPCThreadState有一個PorcessState類型的成中變量mProcess,而mProcess有一個成員變量mDriverFD,它是設備文件/dev/binder的打開文件描述符,因此,IPCThreadState就相當于間接在擁有了設備文件/dev/binder的打開文件描述符,于是,便可以與Binder驅動程序交互了。
對Client來說,就是調用IServiceManager::getService這個接口來和Binder驅動程序交互了。具體過程上述Server使用Service Manager的方法是差不多的。
關于其他內容介紹 01.關于博客匯總鏈接1.技術博客匯總
2.開源項目匯總
3.生活博客匯總
4.喜馬拉雅音頻匯總
5.其他匯總
02.關于我的博客我的個人站點:www.yczbj.org, www.ycbjie.cn
github:https://github.com/yangchong211
知乎:https://www.zhihu.com/people/...
簡書:http://www.jianshu.com/u/b7b2...
csdn:http://my.csdn.net/m0_37700275
喜馬拉雅聽書:http://www.ximalaya.com/zhubo...
開源中國:https://my.oschina.net/zbj161...
泡在網上的日子:http://www.jcodecraeer.com/me...
郵箱:yangchong211@163.com
阿里云博客:https://yq.aliyun.com/users/a... 239.headeruserinfo.3.dT4bcV
segmentfault頭條:https://segmentfault.com/u/xi...
掘金:https://juejin.im/user/593943...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/72849.html
摘要:多進程通信之一命名管道。多進程通信之三信號量與共享內存。共享內存是最快是進程間通信方式,因為個進程之間并不需要數據復制,而是直接操控同一份數據。的一些書籍中甚至不建議新手輕易使用這種進程間通信的方式,因為這是一種極易產生死鎖的解決方案。 [原文地址:https://blog.ti-node.com/blog...] 往往開啟多進程的目的是為了一起干活加速效率,前面說了不同進程之間的內存...
閱讀 3738·2021-09-09 09:33
閱讀 3024·2019-08-30 15:56
閱讀 3017·2019-08-30 15:56
閱讀 3307·2019-08-30 15:55
閱讀 499·2019-08-30 15:53
閱讀 2179·2019-08-30 15:52
閱讀 662·2019-08-28 18:16
閱讀 2391·2019-08-26 13:51