chrome源碼解析系列:chrome線程體系

字號(hào):

那么現(xiàn)在將要深入BrowerProcess和 RenderProces里面去,揭開(kāi)里面有多少線程,線程間怎樣交互。
    考試大提示現(xiàn)有問(wèn)題:
    BrowerProcess中有UI顯示部分,消息接受部分,HTTP頁(yè)面下載部分,然后其他一系列讀取COOKIE,寫文件,讀寫數(shù)據(jù)庫(kù),等操作是怎么協(xié)調(diào)?怎么分工的?之間又是怎么交互的?
    RenderProces中渲染部分和接收 BrowerProcess消息部分是怎么交互的?
    RenderProces是怎么發(fā)送消息的到BrowerProcess中的?
    注意為了方便理解這里先還是先拋開(kāi)PluginProcess和sanbox不講。
    按照上面的問(wèn)題本章打算分三部分介紹:
    一:BrowerProcess 中的線程
    二:RenderProces中的線程
    三:BrowerProcess和RenderProces線程交互流程。
    一:BrowerProcess 中的線程
    BrowerProcess里面的線程很多,其中最重要的是IO線程和UI線程。除了這兩個(gè)線程,還有管理數(shù)據(jù)庫(kù)讀寫的DB線程,管理本地文件讀寫的FILE線程等等。
    要研究每個(gè)線程首先我們得了解每個(gè)線程的職能。
    UI線程顧名思義,管理UI以及UI的消息循環(huán),但是IO線程不能太顧名思義了,IO線程主要有兩方面的職能,接收進(jìn)程間消息(包括渲染進(jìn)程和插件進(jìn)程的消息),還有個(gè)職能是接收網(wǎng)絡(luò)消息所有HTTP頁(yè)面的下載的消息也由這個(gè)線程處理轉(zhuǎn)發(fā),不過(guò)除了用IO來(lái)表示這個(gè)線程也想不出來(lái)更好的名字了J。
    可以先參看下 How Chromium Displays Web Pages 上面的介紹,先引用一張上面的圖片:
    
    (BrowerProcess基本的線程結(jié)構(gòu))
    一個(gè)頁(yè)面是怎樣被創(chuàng)建的呢?
    先弄清楚下面幾點(diǎn)說(shuō)明<靜態(tài)數(shù)據(jù)概念>:
    1:一個(gè)BrowerProcess里面保存一個(gè)Browser的列表,每個(gè)Browser對(duì)象代表著一個(gè)瀏覽器窗口。
    2:每個(gè)Browser對(duì)象里面保存一個(gè)WebContents列表(這個(gè)列表是用了一個(gè)TabStripModel的對(duì)象來(lái)封裝),WebContents就是瀏覽器上面的HTML頁(yè)面和標(biāo)簽。
    3:每個(gè)WebContents中包含了一個(gè)RenderViewHost對(duì)象。這里要多介紹一下WebContents和RenderViewHost各自的功能:RenderViewHost主要表現(xiàn)的就是一個(gè)HTML頁(yè)面,WebContents不說(shuō)大家可能也已經(jīng)猜到了,它就是管理標(biāo)簽命令和導(dǎo)航命令的(HTML頁(yè)面以外的消息由它處理)。
    講一些題外話,GOOGLE聲明說(shuō)他們會(huì)在將來(lái)支持其他程序調(diào)用RenderViewHost的功能,這對(duì)微軟來(lái)說(shuō)是個(gè)相當(dāng)打的挑戰(zhàn),雖然說(shuō)瘦死的駱駝比馬大,但是GOOGLE會(huì)一步步地同食微軟的市場(chǎng),這匹瘦駱駝也無(wú)力于健壯的馬來(lái)競(jìng)爭(zhēng),IE只是他們計(jì)劃中的一個(gè)小計(jì)劃,閑話不多扯了,殺回來(lái)繼續(xù)。
    4:每個(gè)RenderViewHost被創(chuàng)建的時(shí)候它會(huì)創(chuàng)建一個(gè)RenderProcessHost的對(duì)象,并且創(chuàng)建一個(gè)Rander進(jìn)程,RenderProcessHost的對(duì)象會(huì)等待Rander進(jìn)程的連接消息。
    5:一個(gè)RenderProcessHost對(duì)象會(huì)創(chuàng)建一個(gè)ChannelProxy的代理對(duì)象(這個(gè)對(duì)象將被分配到IO線程里面去運(yùn)行),ChannelProxy對(duì)象的職責(zé)是轉(zhuǎn)發(fā)Render進(jìn)程的消息和網(wǎng)絡(luò)消息(HTTP頁(yè)面下載),并且把需要網(wǎng)絡(luò)消息轉(zhuǎn)發(fā)給Render進(jìn)程。RenderProcessHost對(duì)象還會(huì)創(chuàng)建另外一個(gè)過(guò)濾消息的對(duì)象ResourceMessageFilter的過(guò)濾器,該過(guò)濾器會(huì)被添加到ChannelProxy中,此處也是采用上面重復(fù)提到的委托伎倆,ChannelProxy有個(gè)過(guò)濾消息的委托接口類,然后把消息交給由外面派生類(ResourceMessageFilter)來(lái)處理,如果處理了那么就不轉(zhuǎn)發(fā)消息給UI線程了,如果沒(méi)處理,那么轉(zhuǎn)發(fā)消息。
    6:每個(gè)ChannelProxy里面會(huì)包含一個(gè)真正的IPC::Channel對(duì)象,如果看過(guò)我上一篇文章的同學(xué)肯定還記的這個(gè)IPC::Channel,不就是進(jìn)行進(jìn)程間通訊的東東嗎。Channel會(huì)把接受到的消息轉(zhuǎn)發(fā)給ChannelProxy,由ChannelProxy決定該消息路由到什么地方。另外一點(diǎn)就是ChannelProxy會(huì)收到本進(jìn)程的消息(網(wǎng)絡(luò)消息和UI消息和其他的消息),這些消息會(huì)根據(jù)情況被轉(zhuǎn)發(fā)給Render進(jìn)程。
    ChannelProxy在IO線程中是怎么把Message轉(zhuǎn)換為Task的呢?
    可能很奇怪,Message和Task都都好像在前面見(jiàn)過(guò),考試大提示他們之間有什么關(guān)系呢?
    Message是從Render進(jìn)程那兒接受到的消息,TASK是消息循環(huán)中執(zhí)行的一個(gè)任務(wù),IO線程需要把Message轉(zhuǎn)換為TASK發(fā)送到UI線程中去執(zhí)行,Chrome開(kāi)發(fā)人員定義了一套NewRunnableMethod 的方法,用來(lái)把Message轉(zhuǎn)換為相應(yīng)的TASK,參看base\task.h代碼。ChannelProxy里面保存了UI的消息循環(huán)對(duì)象的指針,然后通過(guò)該對(duì)象PostTask系列函數(shù)來(lái)發(fā)送消息到UI線程中。
    一個(gè)對(duì)BrowerProcess里面的進(jìn)程大概介紹就這樣完成了,對(duì)上面的6點(diǎn)我們還可以總結(jié)出 1,2,3是在UI線程環(huán)境中運(yùn)行的,4,5是在IO線程中運(yùn)行的,6是IO和UI線程之間交互方式