Binder機制1---Binder原理介紹

來源:互聯網
上載者:User

標籤:android   style   blog   http   io   使用   ar   strong   sp   

1.Binder通訊機制介紹

這篇文章會先對照Binder機制與Linux的通訊機制的區別,瞭解為什麼Android會另起爐灶,採用Binder。接著,會依據Binder的機制,去理解什麼是Service Manager,在C/S模型中扮演什麼角色。最後,會從一次完整的通訊活動中,去理解Binder通訊的過程。

1.1 Android與Linux通訊機制的比較

儘管Android繼承使用Linux的核心,但Linux與Android的通訊機制不同。

在Linux中使用的IPC通訊機制例如以下:

  1. 傳統IPC:無名pipe, signal, trace, 有名管道
  2. AT&T Unix 系統V:共用記憶體,號誌,訊息佇列
  3. BSD Unix:Socket

而在Android中,並沒有使用這些,取而代之的是Binder機制。Binder機制是採用OpenBinder演化而來,在Android中使用它的原因例如以下:

  1. 採用C/S的通訊模式。而在linux通訊機制中,眼下僅僅有socket支援C/S的通訊模式,但socket有其劣勢,詳細參看第二條。
  2. 有更好的傳輸效能。對照於Linux的通訊機制,
    • socket:是一個通用介面,導致其傳輸效率低,開銷大;
    • 管道和訊息佇列:由於採用儲存轉寄方式,所以至少須要拷貝2次資料,效率低;
    • 共用記憶體:儘管在傳輸時沒有拷貝資料,但其控制機制複雜(比方跨進程通訊時,需擷取對方進程的pid,得多種機制協同操作)。
  3. 安全性更高。Linux的IPC機制在本身的實現中,並沒有安全措施,得依賴上層協議來進行安全控制。而Binder機制的UID/PID是由Binder機制本身在核心空間加入身份標識,安全性高;而且Binder能夠建立私人通道,這是linux的通訊機制所無法實現的(Linux訪問的存取點是開放的)。

綜上所述,Android採用Binder機制是有道理的。既然Binder機制這麼多長處,那麼我們接下來看看它是如何通過C/S模型來實現的。

1.2 Binder在Service服務中的作用

在android中,有非常多Service都是通過binder來通訊的,比方MediaServer旗下包括了眾多service:

  •     AudioFlinger 音頻核心服務
  •     AudioPolicyService:音頻策略相關的重要服務
  •     MediaPlayerService:多媒體系統中的重要服務
  •     CameraService:有關攝像/照相的重要服務

Binder在C/S中的流程例如以下:


  1. Server注冊服務。Server作為眾多Service的擁有者,當它想向Client提供服務時,得先去Service Manager(以後縮寫成SM)那兒注冊自己的服務。Server能夠向SM注冊一個或多個服務。
  2. Client申請服務。Client作為Service的使用者,當它想使用服務時,得向SM申請自己所須要的服務。Client能夠申請一個或多個服務。
  3. 當Client申請服務成功後,Client就能夠使用服務了。
SM一方面管理Server所提供的服務,同一時候又響應Client的請求並為之分配對應的服務。扮演的角色相當於月老,兩邊牽線。這樣的通訊方式的優點是:一方面,service和Client請求便於管理,還有一方面在應用程式開發時,僅僅需為Client建立到Server的串連,就可花非常少時間和精力去實現Server對應功能。那麼,Binder與這個通訊模式有什麼關係呢?!事實上,3者的通訊方式就是Binder機制(比如:Server向SM注冊服務,使用Binder通訊;Client申請請求,用的是Binder通訊)
1.3 Binder通訊機制流程(總體架構)


即是Binder的通訊模型。我們能夠發現:

  1. Client和Server是存在於使用者空間
  2. Client與Server通訊的實現,是由Binder驅動在核心空間實現
  3. SM作為守護進程,處理client請求,管理全部服務項。

為了方便理解,我們能夠把SM理解成DNSserver; 那麼Binder Driver 就相當於路由的功能。這裡就涉及到Client和Server是怎樣通訊的問題。以下對1.2中提到的3個流程進行說明。

1.3.1 Server向SM注冊服務


  1. 首先,XXXServer(XXX代表某個)在自己的進程中向Binder驅動申請建立一個XXXService的Binder的實體,
  2. Binder驅動為這個XXXService建立位於核心中的Binder實體節點以及Binder的引用,注意,是將名字和建立的引用打包傳遞給SM(實體沒有傳給SM),通知SM注冊一個名叫XXX的Service。
  3. SM收到資料包後,從中取出XXXService名字和引用,填入一張尋找表中。
  4. 此時,假設有Client向SM發送申請服務XXXService的請求,那麼SM就能夠在尋找表中找到該Service的Binder引用,並把Binder引用(XXXBpBinder)返回給Client。

在進一步瞭解Binder通訊機制之前,我們先弄清幾個概念。

  1. 引用和實體。這裡,對於一個用於通訊的實體(能夠理解成具有真實空間的Object),能夠有多個該實體的引用(沒有真實空間,能夠理解成實體的一個連結,操作引用就會操作相應連結上的實體)。假設一個進程持有某個實體,其它進程也想操作該實體,最高效的做法是去獲得該實體的引用,再去操作這個引用。
  2. 有些資料把實體稱為本機物件,引用成為遠程對象。能夠這麼理解:引用是從本地進程發送給其它進程來操作實體之用,所以有本地和遠程對象之名。
1.3.2 一個問題-怎樣獲得SM的遠程介面

假設你足夠細心,會發現這裡有一個問題:

Sm和Server都是進程,Server向SM注冊Binder須要處理序間通訊,當前實現的是處理序間通訊卻又用到處理序間通訊。這就好比雞生蛋、蛋生雞,但至少得先有當中之中的一個。

巧妙的Binder解決思路:

針對Binder的通訊機制,Server端擁有的是Binder的實體;Client端擁有的是Binder的引用。
假設把SM看作Server端,讓它在Binder驅動一執行起來時就有自己的Binder實體(代碼中設定ServiceManager的Binder其handle值恒為0)。這個Binder實體沒有名字也不須要注冊,全部的client都覺得handle值為0的binder引用是用來與SM通訊的(代碼中是這麼實現的),那麼這個問題就攻克了。那麼,Client和Server中這麼達成協議了(handle值為0的引用是專門與SM通訊之用的),還不行,還須要讓SM有handle值為0的實體才算大功告成。怎麼實現的呢?!當一個進程調用Binder驅動時,使用BINDER_SET_CONTEXT_MGR命令(在驅動的binder_ioctl中)將自己注冊成SM時,Binder驅動會自己主動為它建立Binder實體。這個Binder的引用對全部的Client都為0。


1.3.3 Client從SM獲得Service的遠程介面


Server向SM注冊了Binder實體及其名字後,Client就能夠通過Service的名字在SM的尋找表中獲得該Binder的引用了(BpBinder)。Client也利用保留的handle值為0的引用向SM請求訪問某個Service:我申請訪問XXXService的引用。SM就會從請求資料包中獲得XXXService的名字,在尋找表中找到該名字相應的條目,取出Binder的引用打包回複給client。之後,Client就能夠利用XXXService的引用使用XXXService的服務了。
假設有很多其它的Client請求該Service,系統中就會有很多其它的Client獲得這個引用。

1.3.4 建立C/S通路後

首先要理清一個概念:client擁有自己Binder的實體,以及Server的Binder的引用;Server擁有自己Binder的實體,以及Client的Binder的引用。我們也能夠從接收方和發送方的方式來理解:

  • 從client向Server發資料:Client為發送方,擁有Binder的實體;Server為接收方,擁有Binder的引用
  • 從server向client發資料:Server為發送方,擁有Binder的實體;client為接收方,擁有Binder的引用。

也就是說,我們在建立了C/S通路後,無需考慮誰是Client誰是Server,僅僅要理清誰是發送方誰是接收方,就能知道Binder的實體和引用在哪邊。


建立CS通路後的流程:(當接收方獲得Binder的實體,發送方獲得Binder的引用後)

  1. 發送方會通過Binder實體請求發送操作。
  2. Binder驅動會處理這個操作請求,把發送方的資料放入寫緩衝(binder_write_read.write_buffer) (對於接收方為讀緩衝區),並把read_size(接收方讀資料)置為資料大小(對於詳細的實現後面會介紹);
  3. 接收方之前一直在堵塞狀態中,當寫緩衝中有資料,則會讀取資料,運行命令操作
  4. 接收方運行完後,會把返回結果相同用binder_transaction_data結構體封裝,寫入寫緩衝區(對於發送方,為讀緩衝區)
1.3.5 匿名Binder

之前在介紹Android使用Binder機制的長處中,提到Binder能夠建立點對點的私人通道,匿名Binder就是這樣的方式。在Binder通訊中,並非全部用來通訊的Binder實體都須要注冊給SM廣而告之的,Server能夠通過已建立的實體Binder串連將建立的Binder實體傳給Client。而這個Binder沒有向SM注冊名字。這樣Server與Client的通訊就有非常高的隱私性和安全性。

這樣,整個Binder的通訊流程就介紹完成了,可是對於詳細的代碼實現(比方binder_transaction_data是什嗎?binder_write_read.write_buffer又是什嗎?詳細的驅動和邏輯實現又是怎麼樣?),在後面章節中會一一介紹。

幾點疑問:
1. 是誰,怎麼樣成為SM守護進程,handle為0的binder實體什麼時候建立?
2.  binder引用和實體是怎樣建立的?在驅動中怎樣實現的通訊?
3. 在SM中,binder實體是如何轉換成為引用的?
4. Server是怎樣注冊服務,Client是怎樣擷取服務的?

讀完興許文章就會知道答案了!

Binder機制1---Binder原理介紹

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.