中文字幕二区_国产精品免费在线观看_黄色网站观看_人人草人人澡_日本真实娇小xxxx

您的位置: 首頁 > 技術(shù)文檔 > 網(wǎng)絡(luò)編程 > Chrome源碼剖析
SQL Server2008 Resource Governor 回到列表 無縫的緩存讀取:雙存儲緩存策略
 Chrome源碼剖析

作者:duguguiyu 時間: 2009-04-02 文檔類型:轉(zhuǎn)載 來自:Venus神廟

第 1 頁
第 2 頁 Chrome的多線程模型 上
第 3 頁 Chrome的多線程模型 下
第 4 頁 Chrome的進(jìn)程間通信 上
第 5 頁 Chrome的多線程模型 中
第 6 頁 Chrome的多線程模型 下
第 7 頁 Chrome的進(jìn)程模型
第 8 頁 Chrome的UI繪制
第 9 頁 Chrome的插件模型

4. 定義IPC消息

如果你寫過MFC程序,對MFC那里面一大堆宏有所忌憚的話,那么很不幸,在Chrome中的IPC消息定義中,你需要再吃一點苦頭了,甚至,更苦大仇深一些;如果你曾經(jīng)領(lǐng)教過用模板的特化偏特化做Traits、用模板做函數(shù)重載、用編譯期的Tuple做變參數(shù)支持,之類機制的種種麻煩的話,那么,同樣很遺憾,在Chrome中,你需要再感受一次。。。

不過,先讓我們忘記宏和模板,看人肉一個消息,到底需要哪些操作。一個標(biāo)準(zhǔn)的IPC消息定義應(yīng)該是類似于這樣的:

class SomeMessage

    : public IPC::Message
{
public:
    enum { ID = ...; }
    SomeMessage(SomeType & data)
        : IPC::Message(MSG_ROUTING_CONTROL, ID, ToString(data))
    {...}
    ...
};

大概意思是這樣的,你需要從Message(或者其他子類)派生出一個子類,該子類有一個獨一無二的ID值,該子類接受一個參數(shù),你需要對這個參數(shù)進(jìn)行序列化。兩個麻煩的地方看的很清楚,如果生成獨一無二的ID值?如何更方便的對任何參數(shù)可以自動的序列化?。。。

在Chrome中,解決這兩個問題的答案,就是宏 + 模板。Chrome為每個消息安排了一種ID規(guī)格,用一個16bits的值來表示,高4位標(biāo)識一個Channel,低12位標(biāo)識一個消息的子id,也就是說,最多可以有16種Channel存在不同的進(jìn)程之間,每一種Channel上可以定義4k的消息。目前,Chrome已經(jīng)用掉了8種Channel(如果A、B進(jìn)程需要雙向通信,在Chrome中,這是兩種不同的Channel,需要定義不同的消息,也就是說,一種雙向的進(jìn)程通信關(guān)系,需要耗費兩個Channel種類...),他們已經(jīng)覺得,16bits的ID格式不夠用了,在將來的某一天,估計就被擴展成了32bits的。書歸正傳,Chrome是這么來定義消息ID的,用一個枚舉類,讓它從高到低往下走,就像這樣:

enum SomeChannel_MsgType

{
    SomeChannelStart = 5 << 12,
    SomeChannelPreStart = (5 << 12) - 1,
    Msg1,
    Msg2,
    Msg3,
    ...
    MsgN,
    SomeChannelEnd
};

這是一個類型為5的Channel的消息ID聲明,由于指明了最開始的兩個值,所以后續(xù)枚舉的值會依次遞減,如此,只要維護(hù)Channel類型的唯一性,就可以維護(hù)所有消息ID的唯一性了(當(dāng)然,前提是不能超過消息上限...)。但是,定義一個ID還不夠,你還需要定義一個使用該消息ID的Message子類。這個步驟不但繁瑣,最重要的,是違反了DIY原則,為了添加一個消息,你需要在兩個地方開工干活,是可忍孰不可忍,于是Google祭出了宏這顆原子彈,需要定義消息,格式如下:

IPC_BEGIN_MESSAGES(PluginProcess, 3)
 
  IPC_MESSAGE_CONTROL2(PluginProcessMsg_CreateChannel,
                       int /* process_id */,
                       HANDLE /* renderer handle */)


  IPC_MESSAGE_CONTROL1(PluginProcessMsg_ShutdownResponse,
                       bool /* ok to shutdown */)


  IPC_MESSAGE_CONTROL1(PluginProcessMsg_PluginMessage,
                       std::vector<uint8> /* opaque data */)


  IPC_MESSAGE_CONTROL0(PluginProcessMsg_BrowserShutdown)


IPC_END_MESSAGES(PluginProcess)

這是Chrome中,定義PluginProcess消息的宏,我挖過來放在這了,如果你想添加一條消息,只需要添加一條類似與IPC_MESSAGE_CONTROL0東東即可,這說明它是一個控制消息,參數(shù)為0個。你基本上可以這樣理解,IPC_BEGIN_MESSAGES就相當(dāng)于完成了一個枚舉開始的聲明,然后中間的每一條,都會在枚舉里面增加一個ID,并聲明一個子類。這個一宏兩吃,直逼北京烤鴨兩吃的高超做法,可以參看ipc_message_macros.h,或者看下面一宏兩吃的一個舉例。。。

多次展開宏的技巧

這是Chrome中用到的一個技巧,定義一次宏,展開多段代碼,我孤陋寡聞,第一次見,一個類似的例子,如下:

首先,定義一個macro.h,里面放置宏的定義:

#undef SUPER_MACRO

#if defined(FIRST_TIME)
#undef FIRST_TIME

#define SUPER_MACRO(label, type) \
enum IDs { \
label##__ID = 10 \
};

#elif defined(SECOND_TIME)
#undef SECOND_TIME

#define SUPER_MACRO(label, type) \
class TestClass \
{ \
public: \
enum {ID = label##__ID}; \
TestClass(type value) : _value(value) {} \
type _value; \
};

#endif

可以看到,這個頭文件是可重入的,每一次先undef掉之前的定義,然后判斷進(jìn)行新的定義。然后,你可以創(chuàng)建一個use_macro.h文件,利用這個宏,定義具體內(nèi)容:

#include "macros.h"

SUPER_MACRO(Test, int)

這個頭文件在利用宏的部分不需要放到ifundef...define...這樣的頭文件保護(hù)中,目的就是為了可重入。在主函數(shù)中,你可以多次define + include,實現(xiàn)多次展開的目的:

#define FIRST_TIME
#include "use_macro.h"

#define SECOND_TIME
#include "use_macro.h"

#include <iostream>

int _tmain(int argc, _TCHAR* argv[])
{
TestClass t(5);
std::cout << TestClass::ID << std::endl;
std::cout << t._value << std::endl;

return 0;
}

這樣,你就成功的實現(xiàn),一次定義,生成多段代碼了。。。

此外,當(dāng)接收到消息后,你還需要處理消息。接收消息的函數(shù),是IPC::Channel::Listener子類的OnMessageReceived函數(shù)。在這個函數(shù)中,會放置一坨的宏,這一套宏,一定能讓你想起MFC的Message Map機制:

    IPC_BEGIN_MESSAGE_MAP_EX(RenderProcessHost, msg, msg_is_ok)

      IPC_MESSAGE_HANDLER(ViewHostMsg_PageContents, OnPageContents)
      IPC_MESSAGE_HANDLER(ViewHostMsg_UpdatedCacheStats,
                          OnUpdatedCacheStats)
      IPC_MESSAGE_UNHANDLED_ERROR()
    IPC_END_MESSAGE_MAP_EX()

這個東西很簡單,展開后基本可以視為一個Switch循環(huán),判斷消息ID,然后將消息,傳遞給對應(yīng)的函數(shù)。與MFC的Message Map比起來,做的事情少多了。。。

通過宏的手段,可以解決消息類聲明和消息的分發(fā)問題,但是自動的序列化還不能支持(所謂自動的序列化,就是不論你是什么類型的參數(shù),幾個參數(shù),都可以直接序列化,不需要另寫代碼...)。在C++這種語言中,所謂自動的序列化,自動的類型識別,自動的XXX,往往都是通過模板來實現(xiàn)的。這些所謂的自動化,其實就是通過事前的大量人肉勞作,和模板自動遞推來實現(xiàn)的,如果說.Net或Java中的自動序列化是過山軌道,這就是那挑夫的驕子,雖然最后都是兩腿不動到了山頂,這底下費得力氣真是天壤之別啊。具體實現(xiàn)技巧,有興趣的看看《STL源碼剖析》,或者是《C++新思維》,或者Chrome中的ipc_message_utils.h,這要說清楚實在不是一兩句的事情。。。

總之通過宏和模板,你可以很簡單的聲明一個消息,這個消息可以傳入各式各樣的參數(shù)(這里用到了夸張的修辭手法,其實,只要是模板實現(xiàn)的自動化,永遠(yuǎn)都是有限制的,在Chrome的模板實現(xiàn)中,參數(shù)數(shù)量不要超過5個,類型需要是基本類型、STL容器等,在不BT的場合,應(yīng)該夠用了...),你可以調(diào)用Channel、ChannelProxy、SyncChannel之類的Send方法,將消息發(fā)送給其他進(jìn)程,并且,實現(xiàn)一個Listener類,用Message Map來分發(fā)消息給對應(yīng)的處理函數(shù)。如此,整個IPC體系搭建完成。。。

苦力的宏和模板

不論是宏還是模板,為了實現(xiàn)這套機制,都需要寫大量的類似代碼,比如為了支持0~N個參數(shù)的Control消息,你就需要寫N+1個類似的宏;為了支持各種基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)的序列化,你就需要寫上十來個類似的Write函數(shù)和Traits。。。

之所以做如此苦力的活,都是為了用這些東西的人能夠盡可能的簡單方便,符合DIY原則。規(guī)約到之前說的設(shè)計者的職責(zé)上來,這是一個典型的苦了我一個幸福千萬人的負(fù)責(zé)任的行為。在Chrome中,如此的代碼隨處可見,光Tuple那一套拳法,我現(xiàn)在就看到了使了不下三次(我曾經(jīng)做過一套,直接吐血...),如此兢兢業(yè)業(yè),真是可歌可泣啊。。。

出處:Venus神廟
責(zé)任編輯:bluehearts

上一頁 Chrome的多線程模型 中 下一頁 Chrome的進(jìn)程模型

◎進(jìn)入論壇網(wǎng)絡(luò)編程版塊參加討論

相關(guān)文章
制作Google Chrome瀏覽器LOGO
web標(biāo)準(zhǔn)優(yōu)秀源碼下載
關(guān)鍵字搜索 常規(guī)搜索 推薦文檔
熱門搜索:CSS Fireworks 設(shè)計比賽 網(wǎng)頁制作 web標(biāo)準(zhǔn) 用戶體驗 UE photoshop Dreamweaver Studio8 Flash 手繪 CG
站點最新 站點最新列表
周大!熬•自然”設(shè)計大賽開啟
國際體驗設(shè)計大會7月將在京舉行
中國國防科技信息中心標(biāo)志征集
云計算如何讓安全問題可控
云計算是多數(shù)企業(yè)唯一擁抱互聯(lián)網(wǎng)的機會
阿里行云
云手機年終巨獻(xiàn),送禮標(biāo)配299起
阿里巴巴CTO王堅的"云和互聯(lián)網(wǎng)觀"
1499元買真八核 云OS雙蛋大促
首屆COCO桌面手機主題設(shè)計大賽
欄目最新 欄目最新列表
淺談JavaScript編程語言的編碼規(guī)范
如何在illustrator中繪制臺歷
Ps簡單繪制一個可愛的鉛筆圖標(biāo)
數(shù)據(jù)同步算法研究
用ps作簡單的作品展示頁面
CSS定位機制之一:普通流
25個最佳最閃亮的Eclipse開發(fā)項目
Illustrator中制作針線縫制文字效果
Photoshop制作印刷凹凸字體
VS2010中創(chuàng)建自定義SQL Rule
>> 分頁 首頁 前頁 后頁 尾頁 頁次:6/91個記錄/頁 轉(zhuǎn)到 頁 共9個記錄

藍(lán)色理想版權(quán)申明:除部分特別聲明不要轉(zhuǎn)載,或者授權(quán)我站獨家播發(fā)的文章外,大家可以自由轉(zhuǎn)載我站點的原創(chuàng)文章,但原作者和來自我站的鏈接必須保留(非我站原創(chuàng)的,按照原來自一節(jié),自行鏈接)。文章版權(quán)歸我站和作者共有。

轉(zhuǎn)載要求:轉(zhuǎn)載之圖片、文件,鏈接請不要盜鏈到本站,且不準(zhǔn)打上各自站點的水印,亦不能抹去我站點水印。

特別注意:本站所提供的攝影照片,插畫,設(shè)計作品,如需使用,請與原作者聯(lián)系,版權(quán)歸原作者所有,文章若有侵犯作者版權(quán),請與我們聯(lián)系,我們將立即刪除修改。

您的評論
用戶名:  口令:
說明:輸入正確的用戶名和密碼才能參與評論。如果您不是本站會員,你可以注冊 為本站會員。
注意:文章中的鏈接、內(nèi)容等需要修改的錯誤,請用報告錯誤,以利文檔及時修改。
不評分 1 2 3 4 5
注意:請不要在評論中含與內(nèi)容無關(guān)的廣告鏈接,違者封ID
請您注意:
·不良評論請用報告管理員,以利管理員及時刪除。
·尊重網(wǎng)上道德,遵守中華人民共和國的各項有關(guān)法律法規(guī)
·承擔(dān)一切因您的行為而直接或間接導(dǎo)致的民事或刑事法律責(zé)任
·本站評論管理人員有權(quán)保留或刪除其管轄評論中的任意內(nèi)容
·您在本站發(fā)表的作品,本站有權(quán)在網(wǎng)站內(nèi)轉(zhuǎn)載或引用
·參與本評論即表明您已經(jīng)閱讀并接受上述條款
推薦文檔 | 打印文檔 | 評論文檔 | 報告錯誤  
專業(yè)書推薦 更多內(nèi)容
網(wǎng)站可用性測試及優(yōu)化指南
《寫給大家看的色彩書1》
《跟我去香港》
眾妙之門—網(wǎng)站UI 設(shè)計之道
《Flex 4.0 RIA開發(fā)寶典》
《贏在設(shè)計》
犀利開發(fā)—jQuery內(nèi)核詳解與實踐
作品集 更多內(nèi)容

雜⑦雜⑧ Gold NORMANA V2