閑聊c/c++ 4: 征服優(yōu)雅喇聊、高效的Libuv庫(kù)之初識(shí)篇

這一系列文章主要分析nodejs中的核心庫(kù)Libuv衣赶。


我的參考書(shū):

樸靈的深入淺出nodejs

Jeffrey Richter的Windows核心編程

Anthony Williams的C++并發(fā)編程實(shí)戰(zhàn)

reference.png

暫定為四篇:

1) 征服之初識(shí)篇(背景基礎(chǔ)以及重要的概念伍茄,圖示)
2) 征服之進(jìn)展篇(libuv的編譯淹朋,例子偏塞,內(nèi)部用到的c語(yǔ)言技巧以及QUEUE的使用)
3) 征服之高潮篇(線(xiàn)程池唱蒸,iocp,同步灸叼,并發(fā)神汹,線(xiàn)程間的通信等)
4) 征服之和諧篇(Libuv的初始化,主循環(huán)古今,主線(xiàn)程和線(xiàn)程池之間的和諧交往)

通過(guò)征服Libuv系列文章屁魏,目的是讓大家了解:

1) C語(yǔ)言之美(語(yǔ)法簡(jiǎn)單,功能強(qiáng)大捉腥,貼近硬件氓拼,適合系統(tǒng)級(jí)別編程,有很多技巧)
2) 多線(xiàn)程與線(xiàn)程的同步技術(shù)
3) 線(xiàn)程池技術(shù)
4) windows IOCP技術(shù)
5) 了解與ms PPL, intel TBB以及l(fā)ibdispatch(ios gcd)之間的異同點(diǎn)和優(yōu)缺點(diǎn)抵碟。
6) vs c++中多線(xiàn)程下的debug技巧

之所以稱(chēng)為了解桃漾,而不是掌握,是因?yàn)檫@些技術(shù)偏向于底層的系統(tǒng)編程拟逮,并不是一撮而就的撬统,需要一定的時(shí)間和經(jīng)歷才能沉淀下來(lái)的。因此只能說(shuō)是讓大家了解敦迄。

為了簡(jiǎn)單期間恋追,一些限制條件:

僅關(guān)注windows下的實(shí)現(xiàn)
僅重點(diǎn)分析libuv的通用cpu密集型計(jì)算的框架,了解cpu密集計(jì)算框架罚屋,實(shí)際上異步io就比較容易理解了
因?yàn)閣indows下苦囱,異步io通過(guò)IOCP(完成端口),會(huì)使代碼實(shí)現(xiàn)非常簡(jiǎn)單沿后,而效率非常高沿彭。

在寫(xiě)此篇blog時(shí),突然感覺(jué)到尖滚,是不是應(yīng)該將libuv庫(kù)進(jìn)行拆分喉刘,將核心部分代碼抽離出來(lái)單獨(dú)運(yùn)行瞧柔,這樣的好處就是要分析的代碼量要少很多,僅關(guān)注我們感興趣的代碼睦裳,有利于演示造锅。

還有一個(gè)目的:
就是在簡(jiǎn)化精華版的基礎(chǔ)上升級(jí)一下,看看是否能夠?qū)崿F(xiàn)任務(wù)的動(dòng)態(tài)均衡(ms PPL庫(kù)和intel TBB庫(kù)都有動(dòng)態(tài)均衡廉邑,Work Stealing的功能哥蔚,libuv目前確定沒(méi)有此功能,libdispatch目前沒(méi)發(fā)現(xiàn)蛛蒙,源碼正在閱讀中糙箍,還沒(méi)看到)。這個(gè)實(shí)現(xiàn)難度還是很大的牵祟,就當(dāng)練練手吧,哈哈

我嘗試一下吧深夯,看看是否可行!


1诺苹、背景:

前段時(shí)間咕晋,完成了一個(gè)微信項(xiàng)目,在后臺(tái)選型過(guò)程中收奔,花了將近一個(gè)月考察了java,php幾個(gè)庫(kù)掌呜,但最終卻選擇了nodejs,原因很簡(jiǎn)單:

1坪哄、java的配置實(shí)在是太麻煩了
2质蕉、php實(shí)在不熟悉,特別扭
3损姜、nodejs使用js編程饰剥,我本人還是比較熟悉js的基礎(chǔ)部分(不算es6.0 es7.0標(biāo)準(zhǔn)),并且npm真好用,實(shí)在是資源太豐富了摧阅,有時(shí)選擇太多也是一種痛苦啊绷蹲!
4棒卷、nodejs基于異步io技術(shù),效率非常高祝钢。而且分布式部署簡(jiǎn)單比规。

通過(guò)無(wú)數(shù)次的比較,最終選定了令我非常滿(mǎn)意的組合拦英,感覺(jué)最起碼少寫(xiě)了80%的代碼蜒什。

后臺(tái)配套方案:

framework: strongloop/loopback(被IBM收購(gòu)了忿危,只能說(shuō)強(qiáng)大無(wú)比)
樸靈的: wechat / wechat-api / wechat-oauth
supersheep: wechat-pay
數(shù)據(jù)庫(kù): mongodb用于不需要事務(wù)處理的表 mysql用于支付的事務(wù)處理
因?yàn)闆](méi)經(jīng)驗(yàn)枉证,在支付時(shí)需要事務(wù)處理,所以調(diào)整為使用mysql。不過(guò)從另外一個(gè)角度說(shuō)明loopback的強(qiáng)大邻辉,支持多數(shù)據(jù)源的統(tǒng)一api操作。

前臺(tái)配套方案:

angularjs1.x
jquery

總體而言熄守,該前后臺(tái)配套系統(tǒng)的開(kāi)發(fā)非常令人愉悅励幼。前臺(tái)不好統(tǒng)計(jì),但是微信后臺(tái)雕什,至少少寫(xiě)了80%代碼2场!

我正在做loopback方面的demo,來(lái)分享一下loopback框架和angularjs之間的互動(dòng)贷岸,你會(huì)看到他們的配合是多么的默契壹士。
近期會(huì)有blog以及demo提交github


2、演變:

目前基于異步回調(diào)的開(kāi)發(fā)非常盛行偿警,例如ios中的gcd躏救,android中的基于接口回調(diào)方式。如果有過(guò)這些開(kāi)發(fā)經(jīng)驗(yàn)户敬,你會(huì)覺(jué)得nodejs的異步事件開(kāi)發(fā)模型還是蠻熟悉的落剪。

隨著逐漸熟悉nodejs,深深的喜歡上了nodejs尿庐,因此更想深入的了解一下nodejs是如何實(shí)現(xiàn)的忠怖。

通過(guò)了解nodejs的代碼結(jié)構(gòu),結(jié)合深入淺出nodejs第三章的異步io所示流程圖抄瑟,逐步驗(yàn)證其正確性凡泣。特別是看到libuv中具有深厚c語(yǔ)言功底的老鳥(niǎo)所寫(xiě)的代碼,忍不住想與大家分享c的代碼之美Fぜ佟鞋拟!

題外話(huà):我深入研究過(guò)的或正在研究的以及即將研究的c源碼庫(kù)

隨便說(shuō)一下:現(xiàn)在c/c++貌似不太流行了。但是不管如何惹资,c語(yǔ)言我認(rèn)為是一門(mén)基礎(chǔ)語(yǔ)言贺纲,每個(gè)程序員如果想要深入了解底層,最好學(xué)一下c語(yǔ)言褪测。

我本人很喜歡c語(yǔ)言猴誊,曾經(jīng)花了5年以上的時(shí)間自己研究3D游戲之父-約翰卡馬克quake系列引擎以及sgi opengl1.21實(shí)現(xiàn)(This is SGI's Sample Implementation of the OpenGL API. It is both a reference implementation and a driver framework used by **almost all commercial 3D hardware vendors **to develop hardware drivers for their systems)。

可以說(shuō)quake引擎以及opengl源碼是形成我科學(xué)程序觀(guān)的基石侮措,是技術(shù)源懈叹。(差點(diǎn)說(shuō)成科學(xué)發(fā)展觀(guān)了,這個(gè)太....)

目前正在閱讀調(diào)試的c庫(kù)源碼:

libdispatch ios gcd中的函數(shù)都是來(lái)源于libdispatch分扎,目前已經(jīng)都移植到linuxwindows中了

libuv 跨平臺(tái)的異步io和work庫(kù)

已編譯并運(yùn)行過(guò)demo,計(jì)劃要閱讀的c源碼庫(kù):

libkqueue 一個(gè)跨平臺(tái)的unix kqueue實(shí)現(xiàn)澄成。實(shí)際在libdispatch移植到windows和linux版本時(shí),就包含了libkqueue。因?yàn)閘ibdispatch(源于macos和ios,他們都是基于unix系統(tǒng)的)基于kqueue實(shí)現(xiàn)墨状。

libzmq跨平臺(tái)的異步消息隊(duì)列庫(kù)(內(nèi)部c++實(shí)現(xiàn)卫漫,以c api方式導(dǎo)出,很多庫(kù)也使用這種方式)

zookeeper是一個(gè)分布式應(yīng)用程序協(xié)調(diào)服務(wù),是Hadoop和Hbase的重要組件。目前作為單獨(dú)一個(gè)庫(kù)獨(dú)立出來(lái)了歉胶。

libuv目前基本了解整個(gè)流程了汛兜,其他幾個(gè)等弄明白了,也一起分享吧通今,讓我們一起來(lái)學(xué)c語(yǔ)言!

為什么選這些庫(kù):
1) 提高自身編程水平最好的方式是多閱讀經(jīng)典源碼
2) 多線(xiàn)程粥谬,異步以及分布式、異步消息隊(duì)列等都是目前主流辫塌,這些庫(kù)是最高水平的實(shí)現(xiàn)漏策,被大規(guī)模,廣泛使用臼氨。
3) 這些庫(kù)都是跨平臺(tái)庫(kù)掺喻,代碼量不大,并且實(shí)用性又很高储矩,功能單一感耙,這就是c庫(kù)的魅力所在。
4) 都是c語(yǔ)言實(shí)現(xiàn)持隧,借助于ide的幫助即硼,會(huì)很容易了解清楚整個(gè)流程。

3屡拨、libuv是什么?

官方介紹:

  libuv is a multi-platform support library with a focus on asynchronous I/O. 
  It was primarily developed for use by Node.js

由上面的介紹只酥,我們可以知道:

1) 跨平臺(tái):windows linux unix都支持
2) 異步io:windows IOCP 、linux epoll呀狼、unix kqueue
3) 主要目的是用于nodejs裂允,實(shí)際還有很多庫(kù)或程序使用了libuv
   例如目前風(fēng)頭正勁的跨平臺(tái).NetCore庫(kù)(就是曾經(jīng)大名鼎鼎的微軟的asp.net)也是使用libuv作為核心
4) libuv不僅僅支持異步io操作,而且還具有一個(gè)強(qiáng)勁的線(xiàn)程池哥艇,用于支持多線(xiàn)程并行的cpu密集型操作绝编。
   這個(gè)才是我們重點(diǎn)要分析的模塊

4、nodejs貌踏、google v8 javascript引擎和libuv之間的關(guān)系:

1) nodejs主要由google v8 javascript引擎和libuv組成
2) v8引擎綁定libuv實(shí)現(xiàn)的api瓮增,因此,既能使用ecma js標(biāo)準(zhǔn)語(yǔ)言來(lái)執(zhí)行js代碼哩俭,又能通過(guò)js調(diào)用libuv相關(guān)接口。
3) 由此可見(jiàn)拳恋,libuv本身是獨(dú)立的c語(yǔ)言庫(kù)凡资,既可以直接使用c/c++來(lái)調(diào)用,也可以被綁定到c#(.NetCore)或者其他任何語(yǔ)言,例如java ,lua......
   c/c++實(shí)現(xiàn)的庫(kù)最大的好處就是能被各種其他編程語(yǔ)言所綁定和調(diào)用隙赁。
   因?yàn)槠渌鞣N編程語(yǔ)言基本都是用c/c++來(lái)實(shí)現(xiàn)的垦藏,都留有接口與c/c++互調(diào)。

借用樸靈 深入淺出nodejs中的兩張圖來(lái)了解整個(gè)流程:

樸靈-深入淺出nodejs-架構(gòu)圖.png
樸靈-深入淺出nodejs-異步調(diào)用示意圖.png

我們libuv源碼分析以上圖為指導(dǎo)伞访,深入挖掘每個(gè)細(xì)節(jié)掂骏,驗(yàn)證其正確性,從而掌握整個(gè)libuv的精髓厚掷!

請(qǐng)將此圖看上100遍弟灼,背出來(lái),肯定有非常大幫助


nodejs就是數(shù)據(jù)通過(guò)v8引擎(主線(xiàn)程:數(shù)據(jù)輸入)傳遞給Libuv進(jìn)行處理(線(xiàn)程池:數(shù)據(jù)處理--根據(jù)數(shù)據(jù)類(lèi)型不同冒黑,io數(shù)據(jù)由IOCP[windows]線(xiàn)程池處理田绑,通用計(jì)算則由自己實(shí)現(xiàn)的線(xiàn)程池處理),libuv處理好后通知v8引擎我已經(jīng)完成了抡爹,你來(lái)進(jìn)行完成處理(主線(xiàn)程:完成回調(diào)掩驱,信息輸出)。


其實(shí)從上面的敘述可以了解到以下幾點(diǎn):
1) v8 javascript引擎是單線(xiàn)程的冬竟,數(shù)據(jù)的輸入欧穴,信息的輸出(完成回調(diào))都是在主線(xiàn)程中處理。這一點(diǎn)以后在源碼分析中我們可以驗(yàn)證泵殴,通過(guò)vs強(qiáng)大的debug功能涮帘,我們可以很清晰的看到具體代碼到底是運(yùn)行在哪個(gè)線(xiàn)程中。
2) 但是數(shù)據(jù)處理模塊(libuv)不是單線(xiàn)程的袋狞,它根據(jù)數(shù)據(jù)請(qǐng)求類(lèi)型是否是io請(qǐng)求(socket,文件讀寫(xiě)或管道等)還是work請(qǐng)求(非io請(qǐng)求)焚辅。不同的請(qǐng)求使用不同的處理策略。例如io請(qǐng)求苟鸯,在windows下用IOCP,在linux下用epool同蜻。而work請(qǐng)求,windows和linux下都是使用統(tǒng)一的早处,自己實(shí)現(xiàn)的線(xiàn)程池湾蔓。而我們的源碼分析就是要證明上面的描述。


下一篇: 征服libuv之進(jìn)展篇

.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末砌梆,一起剝皮案震驚了整個(gè)濱河市默责,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌咸包,老刑警劉巖桃序,帶你破解...
    沈念sama閱讀 211,042評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異烂瘫,居然都是意外死亡媒熊,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)芦鳍,“玉大人嚷往,你說(shuō)我怎么就攤上這事∧疲” “怎么了皮仁?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,674評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀(guān)的道長(zhǎng)菲宴。 經(jīng)常有香客問(wèn)我贷祈,道長(zhǎng),這世上最難降的妖魔是什么裙顽? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,340評(píng)論 1 283
  • 正文 為了忘掉前任付燥,我火速辦了婚禮,結(jié)果婚禮上愈犹,老公的妹妹穿的比我還像新娘键科。我一直安慰自己,他們只是感情好漩怎,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,404評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布勋颖。 她就那樣靜靜地躺著,像睡著了一般勋锤。 火紅的嫁衣襯著肌膚如雪饭玲。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,749評(píng)論 1 289
  • 那天叁执,我揣著相機(jī)與錄音茄厘,去河邊找鬼。 笑死谈宛,一個(gè)胖子當(dāng)著我的面吹牛次哈,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吆录,決...
    沈念sama閱讀 38,902評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼窑滞,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了恢筝?” 一聲冷哼從身側(cè)響起哀卫,我...
    開(kāi)封第一講書(shū)人閱讀 37,662評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎撬槽,沒(méi)想到半個(gè)月后此改,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,110評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡侄柔,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年带斑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鼓寺。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,577評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡勋磕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出敢靡,到底是詐尸還是另有隱情挂滓,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評(píng)論 4 328
  • 正文 年R本政府宣布啸胧,位于F島的核電站赶站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏纺念。R本人自食惡果不足惜贝椿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,848評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望陷谱。 院中可真熱鬧烙博,春花似錦、人聲如沸烟逊。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,726評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)宪躯。三九已至乔宿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間访雪,已是汗流浹背详瑞。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,952評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留臣缀,地道東北人坝橡。 一個(gè)月前我還...
    沈念sama閱讀 46,271評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像肝陪,于是被迫代替她去往敵國(guó)和親驳庭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,452評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容