1. 程式人生 > >Chrome原始碼剖析--Chrome的程序間通訊 上

Chrome原始碼剖析--Chrome的程序間通訊 上

1. Chrome程序通訊的基本模式

程序間通訊,叫做IPC(Inter-Process Communication),在Chrome不多的文件中,有一篇就是介紹這個的,在 這裡 。Chrome最主要有三類程序,一類是Browser主程序,我們一直尊稱它老人家為老大;還有一類是各個Render程序,前面也提過了;另外還有一類一直沒說過,是Plugin程序,每一個外掛,在Chrome中都是以程序的形式呈現,等到後面說外掛的時候再提罷了。Render程序和Plugin程序都與老大保持程序間的通訊,Render程序與Plugin程序之間也有彼此聯絡的通路,唯獨是多個Render程序或多個Plugin程序直接,沒有互相聯絡的途徑,全靠老大協調

。。。

程序與程序間通訊,需要仰仗作業系統的特性,能玩的花著實不多,在Chrome中,用到的就是有名管道(Named Pipe),只不過,它用一個IPC::Channel類,封裝了具體的實現細節。Channel可以有兩種工作模式,一種是Client,一種是Server,Server和Client分屬兩個程序,維繫一個共同的管道名,Server負責建立該管道,Client會嘗試連線該管道,然後雙發往各自管道緩衝區中讀寫資料(在Chrome中,用的是二進位制流,非同步IO...),完成通訊。。。

管道名字的協商

在Socket中,我們會事先約定好通訊的埠,如果不按照這個埠進行訪問,走錯了門,會被直接亂棍打出門去的。與之類似,有名管道期望在兩個程序間遊走,就需要拿一個兩個程序都能接受的進門暗號,這個就是有名管道的名字。在Chrome中(windows下...),有名管道的名字格式都是://./pipe/chrome.ID

。其中的ID,自然是要求獨一無二,比如:程序ID.例項地址.隨機數。通常,這個ID是由一個Process生成(往往是Browser Process),然後在建立另一個程序的時候,作為命令列引數傳進去,從而完成名字的協商。。。

如果不瞭解並期待了解有關Windows下有名管道和訊號量的知識,建議去看一些專業的書籍,比如聖經級別的《Windows核心程式設計》和《深入解析Windows作業系統》,當然也可以去檢視SDK,你需要了解的API可能包括:CreateNamedPipe, CreateFile, ConnectNamedPipe, WaitForMultipleObjects, WaitForSingleObject, SetEvent, 等等。。。

Channel中,有三個比較關鍵的角色,一個是Message::Sender,一個是Channel::Listener,最後一個是MessageLoopForIO::Watcher。Channel本身派生自Sender和Watcher,身兼兩角,而Listener是一個抽象類,具體由Channel的使用者來實現。顧名思義,Sender就是傳送訊息的介面,Listener就是處理接收到訊息的具體實現,但這個Watcher是啥?如果你覺得Watcher這東西看上去很眼熟的話,我會激動的熱淚盈眶的,沒錯,在前面(第一部分第一小節...)說訊息迴圈的時候,從那個表中可以看到,IO執行緒(記住,在Chrome中,IO指的是網路IO,*_*)的迴圈會處理註冊了的Watcher。其實Watcher很簡單,可以視為一個訊號量和一個帶有OnObjectSignaled方法物件的對,當訊息迴圈檢測到訊號量開啟,它就會呼叫相應的OnObjectSignaled方法。。。

圖5 Chrome的IPC處理流程圖

一圖解千語,如上圖所示,整個Chrome最核心的IPC流程都在圖上了,期間,刨去了一些錯誤處理等邏輯,如果想看原汁原味的,可以自查Channel類的實現。當有訊息被Send到一個傳送程序的Channel的時候,Channel會把它放在傳送訊息佇列中,如果此時還正在傳送以前的訊息(傳送端被阻塞...),則看一下阻塞是否解除(用一個等待0秒的訊號量等待函式...),然後將訊息佇列中的內容序列化並寫道管道中去。作業系統會維護非同步模式下管道的這一組訊號量,當訊息從傳送程序緩衝區寫到接收程序的緩衝區後,會啟用接收端的訊號量。當接收程序的訊息迴圈,循到了檢查Watcher這一步,並發現有訊號量激活了,就會呼叫該Watcher相應的OnObjectSignaled方法,通知接受程序的Channel,有訊息來了!Channel會嘗試從管道中收位元組,組訊息,並呼叫Listener來解析該訊息。。。

從上面的描述不難看出,Chrome的程序通訊,最核心的特點,就是利用訊息迴圈來檢查訊號量,而不是直接讓管道阻塞在某訊號量上。這樣就與其多執行緒模型緊密聯絡在了一起,用一種統一的模式來解決問題。並且,由於是訊息迴圈統一檢查,執行緒不會隨便就被阻塞了,可以更好的處理各種其他工作,從理論上講,這是通過增加CPU工作時間,來換取更好的體驗,頗有資本家的派頭。。。

溫柔的訊息迴圈

其實,Chrome的很多訊息迴圈,也不是都那麼霸道,也是會被阻塞在某些訊號量或者某種場景上的,畢竟客戶端不是它家的伺服器,CPU不能被全部歸在它家名下。。。
比如IO執行緒,當沒有訊息來到,又沒有訊號量被啟用的時候,就會被阻塞,具體實現可以去看MessagePumpForIO的WaitForWork方法。。。
不過這種阻塞是集中式的,可隨時修改策略的,比起Channel直接阻塞在訊號量上,停工的時間更短。。。

相關推薦

Chrome原始碼剖析--Chrome程序通訊

1. Chrome程序通訊的基本模式 程序間通訊,叫做IPC(Inter-Process Communication),在Chrome不多的文件中,有一篇就是介紹這個的,在 這裡 。Chrome最主要有三類程序,一類是Browser主程序,我們一直尊稱它老人家為老大;還有一類

Chrome原始碼剖析--Chrome的多執行緒模型

0. Chrome的併發模型 如果你仔細看了前面的圖,對Chrome的執行緒和程序框架應該有了個基本的瞭解。Chrome有一個主程序,稱為Browser程序,它是老大,管理Chrome大部分的日常事務;其次,會有很多Renderer程序,它們圈地而治,各管理一組站點的顯示和通

Android 8.0系統原始碼分析--Binder程序通訊(一)

 開始我們的沉澱之路,老羅的書中第二章講的是Android HAL層的知識,而且直接自己實現了一個虛擬的freg驅動程式,後面的幾節是分別從native、java層如何訪問這個虛擬的驅動程式介面,我這裡沒有這樣的環境,所以就不分析這節了,第三章的智慧指標我對比8.0系統原

Chrome原始碼剖析-- Chrome的外掛模型

1. NPAPI 為了緊密的與各個開源瀏覽器團結起來,共同抗擊IE的壟斷,Chrome的外掛,也遵循了NPAPI(Netscape Plugin Application Programming Interface)標準,支援這個標準的瀏覽器需要實現一組規定的API供外掛呼叫,

Chrome原始碼剖析【二】:【二】Chrome程序通訊

【二】Chrome的程序間通訊 1. Chrome程序通訊的基本模式 程序間通訊,叫做IPC(Inter-Process Communication),在Chrome不多的文件中,有一篇就是介紹這個的,在這裡。Chrome最主要有三類程序,一類是Browser主程序,我們一

Google Chrome原始碼剖析【三】:程序模型

【三】 Chrome的程序模型 1. 基本的程序結構 Chrome是一個多程序的架構,不過所有的程序都會由老大,Browser程序來管理,走的是集中化管理的路子。在Browser程序中,有xxxProcessHost,每一個host,都對應著一個Process,比如Re

Chrome原始碼剖析【三】Chrome程序模型

1. 基本的程序結構 Chrome是一個多程序的架構,不過所有的程序都會由老大,Browser程序來管理,走的是集中化管理的路子。在Browser程序中,有xxxProcessHost,每一個host,都對應著一個Process,比如RenderProcessHost對

Android系統程序通訊 IPC 機制Binder中的Server啟動過程原始碼分析

                        在前面一篇文章中,介紹了在Android系統中Binder程序間通訊機制中的Server角色是如何獲得Service Manager遠端介面的,即defaultServiceManager函式的實現。Server獲得了Service Manager遠端介面之後,

Linux環境程序通訊(五): 共享記憶體()(轉)

轉自http://www.ibm.com/developerworks/cn/linux/l-ipc/part5/index1.html, 作者:鄭彥興採用共享記憶體通訊的一個顯而易見的好處是效率高,因為程序可以直接讀寫記憶體,而不需要任何資料的拷貝。對於像管道和訊息佇列等通訊方式,則需要在內 核和使用者空間

Linux環境程序通訊(二): 訊號()(轉)

訊號本質訊號是在軟體層次上對中斷機制的一種模擬,在原理上,一個程序收到一個訊號與處理器收到一箇中斷請求可以說是一樣的。訊號是非同步的,一個程序不必通過任何操作來等待訊號的到達,事實上,程序也不知道訊號到底什麼時候到達。訊號是程序間通訊機制中唯一的非同步通訊機制,可以看作是非同步通知,通知接收訊號的程序有哪些事

Nginx原始碼分析與實踐---程序通訊機制(訊號)

在前面我們分析了nginx程序間通訊機制的共享記憶體和套接字。這次我們分析剩下一種程序間通訊機制---訊號。 首先要區分訊號和訊號量:訊號是用於程序間通訊的機制,而訊號量是用於保證共享資源不被併發訪問的機制,如可使用訊號量作為互斥鎖實現多程序下對共享資源的同步。 1.nginx中什

Nginx原始碼分析與實踐---程序通訊機制(套接字)

在上一篇中,我們看到了nginx共享記憶體方式的程序間通訊。這次我們看下nginx使用套接字的程序間通訊方式。 同樣的幾個問題: 1.什麼時候需要使用套接字方式的程序間通訊機制呢? 舉個栗子:我們知道nginx有master程序和worker程序,那麼master程序是如何向w

Nginx原始碼分析與實踐---程序通訊機制(共享記憶體)

Nginx有一個master程序和多個worker程序,那麼master程序與worker程序間或worker程序之間是如何通訊的呢,又什麼時候需要程序間通訊呢? 我們知道linux下的程序間通訊方式主要有:管道、FIFO、套接字、訊息佇列、共享記憶體、訊號。那麼nginx的程序間通訊方式採

Google Chrome原始碼剖析【序】

【序】 開源是口好東西,它讓這個充斥著大量工業垃圾程式碼和教材玩具程式碼的行業,多了一些藝術氣息和美的潛質。它使得每個人,無論你來自米國紐約還是中國鐵嶺,都有機會站在巨人的肩膀上,如果不能,至少也可以抱一把大腿。。。 現在我就是來抱大腿的,這條粗腿隸屬於 Chrome(

WindowsC++使用共享記憶體進行程序通訊

共享記憶體 (也叫記憶體對映檔案) 主要是通過對映機制實現的 , Windows 下程序的地址空間在邏輯上是相互隔離的 , 但在物理上卻是重疊的 ; 所謂的重疊是指同一塊記憶體區域可能被多個程序同時使用

程序通訊之-共享記憶體Shared Memory--linux核心剖析(十一)

共享記憶體 共享記憶體是程序間通訊中最簡單的方式之一。 共享記憶體是系統出於多個程序之間通訊的考慮,而預留的的一塊記憶體區。 共享記憶體允許兩個或更多程序訪問同一塊記憶體,就如同 malloc() 函式向不同程序返回了指向同一個實體記憶體區域的指標。當

Chrome原始碼分析之程序和執行緒模型(三)

關於Chrome的執行緒模型,在他的開發文件中有專門的介紹,原文地址在這裡:http://dev.chromium.org/developers/design-documents/threading chrome的程序,chrome沒有采用一般應用程式的單程序多執行緒的模

Chrome原始碼剖析

chrome就不用給大家介紹了,前幾天讀一位兄臺對他原始碼剖析的文章,自己也就拿來看了些,實在是水平有限,沒有深入進去。 只能說按自己的理解和兄臺的文章,說說自己的感受了,在chrome真正讓我有所感悟的是他的多執行緒的處理,很長一段時間來,自己在寫多執行緒的程式,後來把程式

Linux程序通訊的幾種方式總結--linux核心剖析(七)

程序間通訊概述 程序通訊的目的 資料傳輸 一個程序需要將它的資料傳送給另一個程序,傳送的資料量在一個位元組到幾M位元組之間 共享資料 多個程序想要操作共享資料,一個程序對共享資料 通知事 一個程序需要向另一個或一組程序傳送訊息,通知它(它

Chrome原始碼剖析【二】

 【二】Chrome的程序間通訊 1. Chrome程序通訊的基本模式 程序間通訊,叫做IPC(Inter-Process Communication),在Chrome不多的文件中,有一篇就是介紹這個的,在這裡。Chrome最主要有三類程序,一類是Browser主程序,我們