久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

Chromium的多線程機制

 just_person 2013-04-22

轉載請注明出處:http://blog.csdn.net/milado_nju/

# Chromium多線程機制

## 概述

前面我們介紹過Chromium是基于多進程模型的架構設計,那么各個進程內的情況呢,?事實是每個進程都有很多的線程,特別是browser進程,,因而它也基于多線程模型的,。介紹多線程機制之前,先來看一下殘酷的現(xiàn)實吧,,下面是各個進程的線程信息情況(基于Linux平臺,,其它平臺的可能略有不同),,相信保證讓你頭大。是的,,你需要泡杯茶,,然后靜下心來了解一下它們:



為什么這么多的線程呢?Chromium的官方說法告訴我們,,主要目的就是為了保持UI的高響應度,,保證UI線程(chrome線程,主線程)不會被任何其它費時的操作阻礙從而影響了對用戶的響應,。這些其它的操作很多,,例如本地文件讀寫,socket讀寫,,數(shù)據(jù)庫操作等等,。既然它們會阻礙其它操作,那好,,把它們放在單獨的線程里自己忙或者等待去吧,,所以你就看到那么多與這些相關的線程(線程名顯然也暴露了這一切)。

問題來了,,它們直接如何通信和同步呢,?這是多線程的一個非常難纏的問題,因為這會造成死鎖或者競爭沖突等問題,。Chromium精心設計了一套機制來處理它們,,那就是絕大多數(shù)的場景使用事件和一種chromium新創(chuàng)建的任務傳遞機制,僅在非用不可的情況下使用鎖或者線程安全對象,,這有嚴格的要求,,詳細的情況請查看以下鏈接以便作近一步的了解:http://www./developers/lock-and-condition-variable

問題又來了,,那么每個線程內部是如何處理這些事件和任務的呢,?答案是MessageLoop。每個線程會有一個自己的MessageLoop,,它們用來處理這些事件和任務,。通常的MessageLoop只是處理事件,Chromium中的MessageLoop可以同時處理事件和任務,。MessageLoop也是值得研究的,,詳細情況我們將在以后的一章加以介紹。

任務和MessageLoop的基本原理如下圖所示,。任務被派發(fā)到進程的某個線程的MessageLoop的隊列中,,MessageLoop會調度執(zhí)行這些Task。


關于上面這些線程,,多數(shù)可以通過它們的名字猜出用途,,這里鑒于篇幅和噪音考慮,,不一一介紹,下面說明幾個重要和詭異的線程:

chrome線程:進程的主線程,,browser進程重要主要是負責UI,,當然也是管家;Renderer進程中則是管家兼處理WebKit渲染的,;gpu進程中則是負責處理處理繪圖請求并調用openGL進行繪制工作的,。

Chrome_IOThread/Chrome_ChildIOThread線程:用來接受來自其它進程的IPC消息和派發(fā)自身消息到其它進程。

SignalSender線程: V8 JavaScript引擎中用于處理Linux信號的線程,。

##任務(task)

Chromium的特色就是在事件的基礎上,,加入了一個新的機制-任務。當需要執(zhí)行某個操作時候,,可以把該操作封裝成一個任務,,由任務派發(fā)機制傳遞給相應的進程的MessageLoop。

下面看看線程內和線程間分別是如何操作的,。

首先看線程內部是如何進行的,。但你需要進行費時的操作時候,可以派發(fā)一個事件和回調函數(shù)給自身線程的MessageLoop,,然后MessageLoop會調度該回調函數(shù)以執(zhí)行其操作,。問題是這有必要嗎?直接調用不就可以嗎,?答案是不可以,,或者說是最好不要這么做,其原因在于,,如果當前的MessageLoop里面有優(yōu)先級更高的事件和任務需要處理時,,你這樣做會阻礙它們的執(zhí)行。

其次看一看線程間通信,。假如一個線程A需要把任務傳遞給一個另外的線程B,,大致有三個階段:

1.      首先,線程A把該任務傳遞給線程B,;

2.      其次,,線程B調度執(zhí)行該任務;

3.      最后,,線程B執(zhí)行完任務后回復A,。很多情況下,線程A不需要回復,。

下圖描述的是一個帶回復的典型的任務傳遞過程,。


如果不需要回復,那么上圖中的‘Reply Task2’就不需要了。當需要回復時候,,chromium的做法是新建一個新的任務,該任務封裝原來的任務,,新任務被放入線程B,,B執(zhí)行新任務時候調用其Run方法,里面首先執(zhí)行原來的任務,,然后派發(fā)Reply任務給線程A,,操作完成。

后面會有一個具體的例子來描述上面這個過程,,下面了解一下chromium支持Task所涉及的幾個主要類,。

Callback: 回調類,其本質是封裝了一個由調用者(例如線程A)設置的回調函數(shù),。包含一個run方法,,當MessageLoop調度執(zhí)行該Task時候,運行該方法,,該方法調用回調函數(shù)

Closure: 定義為Callback<void(void)>

tracked_objects:一系列的類用于追蹤Task生成位置,,編譯調試

Task: 包含一個Closure,追蹤信息,,表示一個任務

##一個例子

下面用一個實際的例子來理解線程間是如何傳遞任務的,。該例子是chromium中非常常見的一個場景: browser進程接收到來自renderer進程的IPC消息,它由IO線程接收管理,,然后派發(fā)給chrome線程處理,,具體過程如下圖所示:


上面的圖基本上對應了前面的關于任務派發(fā)過程的圖,只是少了回復環(huán)節(jié),,這是因為IO 線程并不需要回復,。基本的步驟是,,當IO線程收到消息后,,其派發(fā)一個任務,該任務將ChannelProxy::Context::OnDispatchMessage設置會回調函數(shù),,這個任務保存在chrome線程的輸入任務隊列中,。chrome線程將輸入隊列拷貝到工作隊列后,執(zhí)行該任務的run方法,,該方法會調用回調函數(shù)ChannelProxy::Context::OnDispatchMessage,,該函數(shù)會調用事件的處理函數(shù),這里也就是RenderProcessHostImpl::OnMessageReceived,,這個函數(shù)實際上會根據(jù)事件類型來調用各個相應函數(shù),。

## 源文件目錄

base/threading/

         線程相關的基礎類

## 參考文獻

1.      http://www./developers/design-documents/threading

2.      http:///archives/478

3.      http://www./developers/lock-and-condition-variable

By yongsheng@

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點,。請注意甄別內容中的聯(lián)系方式,、誘導購買等信息,謹防詐騙,。如發(fā)現(xiàn)有害或侵權內容,,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多