大牛用愛情故事來講Binder通信原理,一招搞定Binder進程通信架構

作者:鴻洋

原文鏈接:https://mp.weixin.qq.com/s/zPVe1IRjNKKx2l5RVCc1Jw

前言

對Binder學習感興趣的小夥伴可以看看,希望能幫助到你們。

爲什麼會有Binder通信機制,爲什麼不能用linux中已有的進程框架呢?Google工程師究竟是如何考量的?

這一切可以通過一場戀愛來理解?

瞭解binder之前我們看看原有Linux進程是如何通信的吧!爲什麼需要在內存中拷貝兩次呢?

在瞭解Linux進程通信前我們先理解下 戀愛的故事吧!

故事:

男孩和女孩在某次旅遊一見鍾情,而旅行結束的他們不得不返回各自的工作城市

大牛用愛情故事來講Binder通信原理,一招搞定Binder進程通信架構

那個時代還沒有微信,由於相隔在不同的城市。相思的他們只能通過郵局抒發彼此愛慕之情

如果男孩想要給女孩發送信封,需要向本地郵局 寄信。再有全國郵局轉發到 女孩所在的本地郵局

最後由本地郵局送到女孩手中

在進程中的角色:

男孩 稱爲進程A,工作城市A城,女孩稱爲進程B,工作城市B城

本地郵局稱爲用戶空間, 全國郵局稱爲內核空間

本地郵局是他們離的最近的地方。他們可以接觸到本地郵局,可以在郵局中直接收信和發信

大牛用愛情故事來講Binder通信原理,一招搞定Binder進程通信架構

1.1 這是普通linux進程通信的方式

轉換專業術語的圖

進程間,用戶空間的數據不可共享(本地郵局是男孩或女孩獨有),所以用戶空間相當於私有空間。

進程間,內核空間的數據可共享(全國郵局是所有人共有),所以內核空間 相當於公共空間。

進程間如果需要做到通信,需要通過共享空間對數據轉換。轉換過程需要調用系統的api,這個過程稱爲系統調用。

大牛用愛情故事來講Binder通信原理,一招搞定Binder進程通信架構

問題來了:

男孩寫好信之後,發送信件給本地郵局 , 相當於一次拷貝 我們把這個過程稱爲(copy_from_user)

女孩收到當地郵局通知,需要從本地郵局取信。相當於第二次拷貝,我們把這個過程稱爲(copy_to_user)

這就是Linux已有進程間通信方式。

兩次拷貝究竟性能怎麼樣,當然拷貝是非常耗性能的,而兩次拷貝可以再優化優化。

那binder是怎麼做到一次拷貝的呢

1.2接着講愛情的例子(Binder的實現機制)

後來在疫情結束後,這個女孩去了全國郵局依賴的快遞公司上班去了,所有的信封需要用快遞公司來處理,剛好這家快遞公司處理的是他們兩個城市的信件。

大牛用愛情故事來講Binder通信原理,一招搞定Binder進程通信架構

爲了方便收信封,居然還有這操作

大牛用愛情故事來講Binder通信原理,一招搞定Binder進程通信架構

這就給女孩創造了便利,不用去本地郵局取信件

大牛用愛情故事來講Binder通信原理,一招搞定Binder進程通信架構

但是男孩還是要發送信件。binder拷貝也是發生在男孩這個地方copyfromuser,女孩由於在快遞公司上班,可以隨意瀏覽男孩的信件。不需要再取信件了。也就減少了從本地郵局取快遞這次拷貝過程

思考: 大家還記不記得接收端怎麼寫的,對! 接收端一定必須是服務Service,接收端不能是其他java對象。Service就是那個女孩。她必須在快遞公司上班才能減少一次拷貝。所以這個Service,在通信前會註冊在ServiceManager中。而男孩可以是任意對象,出現在任意地方。

Linux 已有的進程通信,發送端和接收端可以是任意對象。出現在任意類中。但是必須犧牲多拷貝一次

Android的Binder通信,接收端不能是任意對象,只能是Service,這也節約了一次拷貝,犧牲了開發者的體驗

1.3 Binder少拷貝一次的原理:

全國郵局 相當於內核空間的內存,所有的應用都與內核空間的內存發生頻繁的調用,在Binder中傳遞數據本質上是通過文件讀取來實現的

大家記不記得Linux系統 是文件操作系統,都是基於文件展開的。進程通信中 File也能實現進程通信

Binder機制中 在內存與文件中設計了一層映射關係。內核空間的內存是虛的,文件IO是實的。映射指的是內存與文件的映射,映射是通過mmap函數。

而mmap函數 需要依賴一個文件,這個文件叫做“binder”。對!他沒有後綴名,他就是一個文件。但是人們習慣性的把它稱爲binder驅動。

我們再來看看實際的是如何映射的

全國郵局中的A城與B城的信件,相當於內核空間內存一部分虛擬內存區域。

A城與B城的快遞公司,相當於文件實體。實際信封是由快遞公司轉發。郵局與快遞公司的合作關係,可以理解內存與文件形成了映射關係(mmap)

大牛用愛情故事來講Binder通信原理,一招搞定Binder進程通信架構

1.4 服務端Service 也通過mmap函數監聽文件的變化。

一旦有信件到達女孩的公司直接讀取出來,而不用去本地郵局取信件。

女孩怎麼在公司取出來呢?大家忘記了女孩在快遞公司上班呢,快遞公司會給員工佈置工作內容

女孩的工作內容是查看快遞接收站和發送站的信封

這樣你說能不能看到男朋友發過來的信件,還不用親自跑到本地郵局,那不是爽歪歪

綠色部分 是女孩進程,綠色內有兩個角色(女孩接觸到的 接收站和收發站)

大牛用愛情故事來講Binder通信原理,一招搞定Binder進程通信架構

這一套機制的實現基於 aidl文件編譯機制

在編譯時生成了一個繼承自Binder中的IInterface接口(女孩)。接口中有這樣一個內部類叫Stub(女孩工作接觸的接收站)和一個內部類叫Proxy(女孩工作接觸的發送站)

男孩信封到了,女孩直接在 快遞接收站查看男孩發過來的信封(Stub中的 onTransact方法)

女孩思戀男孩,給男孩發送信封(Proxy中的transact方法)

Stub與Proxy中所有的方法是native直接調用過來的。參數是直接從內核空間傳遞過來的,不需要發生拷貝。

如果女孩需要給男孩發送消息,也不用跑到本地郵局,直接在 快遞發送站,插入一個信封就好了(調用Proxy的transct方法)

減少一次拷貝發生在 服務端service。直接由nativie層 的Binder調起。不需要再次拷貝。

大家看完了 是不是對整個Binder機制有深刻的認識呢?

如果還不是很理解的,可以來看一下我搜集的一些關於Binder的詳細系統的學習資料和視頻從爲什麼會有Binder,到Binder原理,最後從Binder中mmap函數 能爲實際工作中解決儲存的問題。

從Binder的底層原理分析,讓Android開發者真正瞭解到Binder的通信機制。從Linux進程通信技術認知到爲什麼Android會選擇Binder作爲通信方式,到Linux的進程原理,最後借鑑Binder中mmap函數打造優異的存儲框架。

有需要的小夥伴可以私信我Binder】我分享給你

希望在2020 資本寒冬和疫情的情況下,大家都能抓住這次機會,在這段時間內努力提升自己技術,把自己變得更優秀,成爲不可替代的人。最後找到自己滿意的工作。

330頁Android進階核心筆記

大牛用愛情故事來講Binder通信原理,一招搞定Binder進程通信架構

精選Binder進階視頻

大牛用愛情故事來講Binder通信原理,一招搞定Binder進程通信架構
B站賬號:bili_84936792704 希望資料加視頻可以提高大家學習的效率。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章