亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

征服優雅、高效的Libuv庫之初識篇

發布時間:2020-07-14 21:20:51 來源:網絡 閱讀:17294 作者:jackyBLF 欄目:系統運維


這一系列文章主要分析nodejs中的核心庫Libuv。


我的參考書:

樸靈的深入淺出nodejs

Jeffrey Richter的Windows核心編程

Anthony Williams的C++并發編程實戰

征服優雅、高效的Libuv庫之初識篇


暫定為四篇:

1) 征服之初識篇(背景基礎以及重要的概念,圖示,libuv的編譯,例子)
2) 征服之進展篇(內部用到的c語言技巧以及QUEUE的使用)
3) 征服之高潮篇(線程池,iocp,同步,并發,線程間的通信等)
4) 征服之和諧篇(Libuv的初始化,主循環,主線程和線程池之間的和諧交往)

通過征服Libuv系列文章,目的是讓大家了解:

1) C語言之美(語法簡單,功能強大,貼近硬件,適合系統級別編程,有很多技巧)
2) 多線程與線程的同步技術
3) 線程池技術
4) windows IOCP技術
5) 了解與ms PPL, intel TBB以及libdispatch(ios gcd)之間的異同點和優缺點。
6) vs c++中多線程下的debug技巧

之所以稱為了解,而不是掌握,是因為這些技術偏向于底層的系統編程,并不是一撮而就的,需要一定的時間和經歷才能沉淀下來的。因此只能說是讓大家了解。

為了簡單期間,一些限制條件:

僅關注windows下的實現
僅重點分析libuv的通用cpu密集型計算的框架,了解cpu密集計算框架,實際上異步io就比較容易理解了
因為windows下,異步io通過IOCP(完成端口),會使代碼實現非常簡單,而效率非常高。

在寫此篇blog時,突然感覺到,是不是應該將libuv庫進行拆分,將核心部分代碼抽離出來單獨運行,這樣的好處就是要分析的代碼量要少很多,僅關注我們感興趣的代碼,有利于演示。

還有一個目的:

就是在簡化精華版的基礎上升級一下,看看是否能夠實現任務的動態均衡(ms PPL庫和intel TBB庫都有動態均衡,Work Stealing的功能,libuv目前確定沒有此功能,libdispatch目前沒發現,源碼正在閱讀中,還沒看到)。這個實現難度還是很大的,就當練練手吧,哈哈

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

(本文寫于2016年,經過這段時間研究,于2017-2-10放棄上面的拆分這個想法,實在是牽涉到的代碼以及操作系統太多,還是果斷放棄這個念想吧!)


1、背景:

前段時間,完成了一個微信項目,在后臺選型過程中,花了將近一個月考察了java,php幾個庫,但最終卻選擇了nodejs,原因很簡單:

1、java的配置實在是太麻煩了
2、php實在不熟悉,特別扭
3、nodejs使用js編程,我本人還是比較熟悉js的基礎部分(不算es6.0 es7.0標準),并且npm真好用,實在是資源太豐富了,有時選擇太多也是一種痛苦啊!
4、nodejs基于異步io技術,效率非常高。而且分布式部署簡單。

通過無數次的比較,最終選定了令我非常滿意的組合,感覺最起碼少寫了80%的代碼。

后臺配套方案:

framework: strongloop/loopback(被IBM收購了,只能說強大無比)
     樸靈的: wechat / wechat-api / wechat-oauth
      supersheep: wechat-pay
     數據庫: mongodb用于不需要事務處理的表 mysql用于支付的事務處理
因為沒經驗,在支付時需要事務處理,所以調整為使用mysql。不過從另外一個角度說明loopback的強大,支持多數據源的統一api操作。

前臺配套方案:

angularjs1.x
jquery

總體而言,該前后臺配套系統的開發非常令人愉悅。前臺不好統計,但是微信后臺,至少少寫了80%代碼!!

2、演變:

目前基于異步回調的開發非常盛行,例如ios中的gcd,android中的基于接口回調方式。如果有過這些開發經驗,你會覺得nodejs的異步事件開發模型還是蠻熟悉的。

隨著逐漸熟悉nodejs,深深的喜歡上了nodejs,因此更想深入的了解一下nodejs是如何實現的。

通過了解nodejs的代碼結構,結合深入淺出nodejs第三章的異步io所示流程圖,逐步驗證其正確性。特別是看到libuv中具有深厚c語言功底的老鳥所寫的代碼,忍不住想與大家分享c的代碼之美!!

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) 跨平臺:windows linux unix都支持
2) 異步io:windows IOCP 、linux epoll、unix kqueue
3) 主要目的是用于nodejs,實際還有很多庫或程序使用了libuv
   例如目前風頭正勁的跨平臺.NetCore庫(就是曾經大名鼎鼎的微軟的asp.net)也是使用libuv作為核心
4) libuv不僅僅支持異步io操作,而且還具有一個強勁的線程池,用于支持多線程并行的cpu密集型操作。
   這個才是我們重點要分析的模塊

4、nodejs、google v8 javascript引擎和libuv之間的關系:

1) nodejs主要由google v8 javascript引擎和libuv組成
2) v8引擎綁定libuv實現的api,因此,既能使用ecma js標準語言來執行js代碼,又能通過js調用libuv相關接口。
3) 由此可見,libuv本身是獨立的c語言庫,既可以直接使用c/c++來調用,也可以被綁定到c#(.NetCore)或者其他任何語言,例如java ,lua......
   c/c++實現的庫最大的好處就是能被各種其他編程語言所綁定和調用。
   因為其他各種編程語言基本都是用c/c++來實現的,都留有接口與c/c++互調。

借用深入淺出nodejs(經作者同意)中的兩張圖來了解整個流程:

征服優雅、高效的Libuv庫之初識篇

征服優雅、高效的Libuv庫之初識篇


我們libuv源碼分析以上圖為指導,深入挖掘每個細節,驗證其正確性,從而掌握整個libuv的精髓!

一定要明確的了解哪些事情是發生在主線程的,哪些事情是發生在線程池中的!!!

請將此圖看上100遍,背出來,肯定有非常大幫助


nodejs就是數據通過v8引擎(主線程:數據輸入)傳遞給Libuv進行處理(線程池:數據處理—根據數據類型不同,io數據由IOCP[windows]線程池處理,通用計算則由自己實現的線程池處理),libuv處理好后通知v8引擎我已經完成了,你來進行完成處理(主線程:完成回調,信息輸出)。


其實從上面的敘述可以了解到以下幾點:


   1) v8 javascript引擎是單線程的,數據的輸入,信息的輸出(完成回調)都是在主線程中處理。這一點以后在源碼分析中我們可以驗證,通過vs強大的debug功能,我們可以很清晰的看到具體代碼到底是運行在哪個線程中。


   2) 但是數據處理模塊(libuv)不是單線程的,它根據數據請求類型是否是io請求(socket,文件讀寫或管道等)還是work請求(非io請求)。不同的請求使用不同的處理策略。例如io請求,在windows下用IOCP,在linux下用epool。而work請求,windows和linux下都是使用統一的,自己實現的線程池。而我們的源碼分析就是要證明上面的描述。


5、visual studio編譯及測試Libuv庫:

   1) 如何編譯libuv庫
   2) 在測試libuv庫的時候,如何解決各種鏈接錯誤
   3) 重點是根據鏈接錯誤編號,通過msdn來定位問題、分析問題以及解決問題,掌握方法學是關鍵


編譯:
   1) 安裝python2.,6或者2.7版本,并設置好環境變量。千萬別安裝3.0或以上版本。
      目前很多跨平臺庫,都通過python腳本進行編譯或引導,因此python是必裝程序。、


   2) 在cmd中:
       cd到你libuv所在目錄
       并輸入 git clone https://chromium.googlesource.com/external/gyp.git build/gyp
       將google gyp系統克隆到libuv所在目錄的build/gyp文件夾下面
       由于GFW的關系,google網站無法訪問,作為程序員,我想你應該有辦法、


   3) 運行libuv所在目錄下的vcbuild.bat,生成visual studio解決方案。雙擊運行,然后F5編譯調試,一切盡在掌握中!


如果你目前可以登陸google網站,則直接運行vcbuild.bat,如果沒安裝過gyp的話,自動會下載gyp構建系統。因此可以省略第二步

征服優雅、高效的Libuv庫之初識篇

雙擊uv.sln工程,f5編譯,一路順風順水,毫無難度!

2、如何測試運行:

因為Libuv在windows中編譯后的結果是一個靜態鏈接庫,那么我們需要重新建個exe工程,并將libuv.lib鏈接入exe這個程序,步驟如下:

1) 新建一個win32/控制臺/空項目,名稱例如:LibuvTest


征服優雅、高效的Libuv庫之初識篇

征服優雅、高效的Libuv庫之初識篇

2) 在源文件中添加main.cpp文件,實現以下簡單代碼并運行,F5,調試運行

征服優雅、高效的Libuv庫之初識篇

3) 如果運行時報無法啟動程序,則將exe設置為啟動項:


征服優雅、高效的Libuv庫之初識篇

征服優雅、高效的Libuv庫之初識篇

4) 使用uv_wort_t進行cpu密集計算的測試代碼,F5編譯調試

征服優雅、高效的Libuv庫之初識篇


征服優雅、高效的Libuv庫之初識篇

F5運行后出現鏈接錯誤

5) LNK2019鏈接錯誤,表示相關的Lib沒有被引入,觀察相關錯誤內容,可以確定Libuv.lib沒有被導入。

1、查找到Libuv.lib被編譯到的目錄

征服優雅、高效的Libuv庫之初識篇

2、在LibuvTest項目上右擊鼠標,選擇屬性菜單,彈出libuvTest Property Pages,然后選擇Linker/input/Additional Dependencies界面

征服優雅、高效的Libuv庫之初識篇

3、相對路徑方式,添加libuv.lib庫

征服優雅、高效的Libuv庫之初識篇

參考

6) 添加好libuv.lib后,繼續F5調試,仍舊有大量鏈接錯誤:

征服優雅、高效的Libuv庫之初識篇

7) 解決LNK4098錯誤,該錯誤是由于LIBCMTD庫引起的,我們忽略該庫,具體如下:

征服優雅、高效的Libuv庫之初識篇

8) 解決LNK2019錯誤,該錯誤前面也提到過,是由于沒有引入相應的lib導致的。

1、查看具體的鏈接錯誤描述,可以看到和socket相關的

征服優雅、高效的Libuv庫之初識篇

2、msdn是法寶,在msdn中查找closesocket函數,看看closesocket屬于哪個lib庫的?

征服優雅、高效的Libuv庫之初識篇

3、按照前面添加libuv.lib方式(),添加Ws2_32.lib。或者也可以參考該文檔使用另外一種方式:#pragma comment(lib,”path”)方式進行鏈接。

9) 周而復始,不斷使用8)的方式,解決所有LNK2019鏈接錯誤

征服優雅、高效的Libuv庫之初識篇



征服優雅、高效的Libuv庫之初識篇

征服優雅、高效的Libuv庫之初識篇

征服優雅、高效的Libuv庫之初識篇

10) 最終需要的所有鏈接庫

征服優雅、高效的Libuv庫之初識篇

11) F5繼續編譯調試,正確運行輸出結果

征服優雅、高效的Libuv庫之初識篇

12) 至此為止,libuv的uv_work_t的Demo能夠編譯并且正確運行。我們也可以休息一下了!


可能太基礎了,但是也是體現了解決問題的方法,一并記錄下來,供大家參考。


下一篇我們關注libuv中一個重要的數據結構:QUEUE的實現和使用。

該結構在多個線程之間傳送數據,因此必須要深入了解其原理和實現。



向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

兴仁县| 嘉黎县| 通城县| 彭山县| 明光市| 栾城县| 龙州县| 天津市| 阳江市| 谢通门县| 龙泉市| 江孜县| 霍州市| 太康县| 宝兴县| 肃北| 托克托县| 桂东县| 柳州市| 渝中区| 晋州市| 麦盖提县| 尖扎县| 姚安县| 昭平县| 田东县| 隆回县| 清丰县| 靖宇县| 深水埗区| 古丈县| 康保县| 隆子县| 闵行区| 佛教| 天全县| 呼伦贝尔市| 垫江县| 石狮市| 定结县| 科尔|