摘要:而線程是進(jìn)程的一部分,二者相扶相依,其中單線程被稱為輕權(quán)進(jìn)程或輕量級進(jìn)程,執(zhí)行特性線程只有個基本狀態(tài)就緒,執(zhí)行,阻塞。以上所述證明了操作與其他函數(shù)的這種區(qū)別是由實現(xiàn),是用多線程的方式,在標(biāo)準(zhǔn)的阻塞式上模擬非阻塞異步,線程池默認(rèn)限制四線程。
node - 非阻塞的異步 IO
每當(dāng)我們提起 node.js 時總會脫口而出 事件驅(qū)動、非阻塞I/O 和 單線程,所以我總結(jié)了以下幾點對這三項概念的闡述,不一定正確僅僅代表個人觀點。
單線程當(dāng)一個應(yīng)用程序運行時會產(chǎn)生一個主進(jìn)程,它與其他并行執(zhí)行的應(yīng)用程序一起竟?fàn)幱嬎銠C系統(tǒng)資源,是管理和分配現(xiàn)有所占據(jù)資源的基本單位。每一個進(jìn)程都有一個自己的地址空間(進(jìn)程空間)。而線程是進(jìn)程的一部分,二者相扶相依,其中單線程被稱為輕權(quán)進(jìn)程或輕量級進(jìn)程,執(zhí)行特性:
線程只有 3 個基本狀態(tài):就緒,執(zhí)行,阻塞。
線程存在 5 種基本操作來切換線程的狀態(tài):派生,阻塞,激活,調(diào)度,結(jié)束。
下面這個圖片簡單解釋了單線程的運作:
用 php、apache、nginx 和 node.js 做對比是因為這四個應(yīng)用恰好代表四種情況,其中 php 是典型的多線程的語言,apache 則是同步多進(jìn)程的代表,也就是說連接每一個連接 apache 都對應(yīng)一個子進(jìn)程,而 nginx 是異步多線程,近萬個連接對應(yīng)一個子進(jìn)程。
線程與非阻塞IO當(dāng)我們說 node.js 是單線程應(yīng)用的時候,實際上這種單線程只是代碼執(zhí)行主程序上的單線程,在涉及到 IO 操作時仍然是多線程,下面我們看一段代碼:
var path = require("path"), fs = require("fs"); var i = 0; console.time("fs.read"); fs.read(fs.openSync(path.join(__dirname, "example.log"), "r"), 10000, 0, "utf-8", function () { console.log("1"); console.timeEnd("fs.read"); }); console.log("2"); function test(cb) { console.time("test"); console.log("3"); while (i < 300000000) { i++ } cb() } console.log("4"); test(function () { console.log("5"); console.timeEnd("test"); }); console.log("6"); //process.exit();
運行結(jié)果時:
數(shù)字標(biāo)識分別為2、4、3、5、6、1,fs 和 test 同樣是回調(diào)函數(shù)一個立即執(zhí)行并順序執(zhí)行,而另一個延遲執(zhí)行,這顯然不符合傳統(tǒng)的程序執(zhí)行順序,也不符合有些人說的: 這種以定義當(dāng)前感興趣事件發(fā)生時由系統(tǒng)調(diào)用的函數(shù)來取代應(yīng)用返回值的編程風(fēng)格被稱為事件驅(qū)動編程或者異步編程,這句話的錯誤在于是事件驅(qū)動編程 但不一定是異步編程,異步編程 的先決條件是當(dāng)前執(zhí)行函數(shù)正在進(jìn)行 IO 操作。
如果我們把上述代碼的最后一句 //process.exit(); 的注釋拿掉,可以看到執(zhí)行結(jié)果:
這種情況是因為 fs 的 IO 操作是異步,并且執(zhí)行結(jié)果在 事件驅(qū)動編程 的 事件隊列 的最低端,而在它之前 process.exit(); 已經(jīng)在 事件循環(huán) 過程中被從事件隊列中取出放入調(diào)用堆棧,結(jié)束了主進(jìn)程。所以發(fā)生 fs 的回調(diào)結(jié)果沒有顯示,因為它已經(jīng)被放在了整段代碼執(zhí)行環(huán)境中的 事件隊列 的最下方(這里就是非阻塞的實例)。
以上所述證明了 IO 操作與其他函數(shù)的這種區(qū)別是由 libeio 實現(xiàn),libeio 是用多線程的方式,在標(biāo)準(zhǔn)的阻塞式IO上模擬非阻塞異步,線程池默認(rèn)限制四線程。
另外的 libev 事件可得到 IO 執(zhí)行狀態(tài)。Node.js 的開發(fā)者在 libev 和 libeio 的基礎(chǔ)上還抽象出了 libuv 層: (http://docs.libuv.org/en/v1.x/design.html)。
所有的 IO操作都會轉(zhuǎn)發(fā)給由 libuv 管理的工作線程去執(zhí)行,由 libuv 與 libev 和 libeio 進(jìn)行交互。
事件驅(qū)動與事件循環(huán)互為犄角,其中事件循環(huán)具備兩個功能:
事件檢測
事件觸發(fā)處理
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/111349.html
摘要:給出了解決方案就是單線程,遠(yuǎn)離線程鎖,狀態(tài)同步的問題,使用異步讓單線程遠(yuǎn)離阻塞,高效利用。而實際上的異步是采用了線程池技術(shù),發(fā)起異步時,把操作扔到線程池里面執(zhí)行,然后主線程繼續(xù)執(zhí)行其他操作,執(zhí)行完畢通過線程間通信通知主線程,主線程執(zhí)行回調(diào)。 異步IO,事件驅(qū)動,單線程構(gòu)成了node的基調(diào),為什么異步IO在node中如此重要呢? 我們先來說一下異步的概念,異步常見于前端開發(fā),例如ajax...
摘要:而線程是進(jìn)程的一部分,二者相扶相依,其中單線程被稱為輕權(quán)進(jìn)程或輕量級進(jìn)程,執(zhí)行特性線程只有個基本狀態(tài)就緒,執(zhí)行,阻塞。以上所述證明了操作與其他函數(shù)的這種區(qū)別是由實現(xiàn),是用多線程的方式,在標(biāo)準(zhǔn)的阻塞式上模擬非阻塞異步,線程池默認(rèn)限制四線程。 node - 非阻塞的異步 IO 每當(dāng)我們提起 node.js 時總會脫口而出 事件驅(qū)動、非阻塞I/O 和 單線程,所以我總結(jié)了以下幾點對這三項概念...
摘要:而線程是進(jìn)程的一部分,二者相扶相依,其中單線程被稱為輕權(quán)進(jìn)程或輕量級進(jìn)程,執(zhí)行特性線程只有個基本狀態(tài)就緒,執(zhí)行,阻塞。以上所述證明了操作與其他函數(shù)的這種區(qū)別是由實現(xiàn),是用多線程的方式,在標(biāo)準(zhǔn)的阻塞式上模擬非阻塞異步,線程池默認(rèn)限制四線程。 node - 非阻塞的異步 IO 每當(dāng)我們提起 node.js 時總會脫口而出 事件驅(qū)動、非阻塞I/O 和 單線程,所以我總結(jié)了以下幾點對這三項概念...
閱讀 2641·2021-11-18 10:07
閱讀 1090·2021-08-03 14:04
閱讀 733·2019-08-30 13:08
閱讀 2587·2019-08-29 15:33
閱讀 1102·2019-08-29 14:07
閱讀 3002·2019-08-29 14:04
閱讀 1448·2019-08-29 11:19
閱讀 1155·2019-08-29 10:59