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