3 回答

TA貢獻(xiàn)1946條經(jīng)驗(yàn) 獲得超3個(gè)贊
您對(duì)節(jié)點(diǎn)如何工作的理解是不正確的……但這是一個(gè)常見的誤解,因?yàn)檫@種情況的實(shí)際情況實(shí)際上相當(dāng)復(fù)雜,并且通常歸結(jié)為諸如“ node is single threaded”之類的小詞,過分簡(jiǎn)化了事情。
目前,我們將忽略通過集群和webworker-threads進(jìn)行的顯式多處理/多線程,而僅討論典型的非線程節(jié)點(diǎn)。
節(jié)點(diǎn)在單個(gè)事件循環(huán)中運(yùn)行。它是單線程的,您只能獲得一個(gè)線程。您編寫的所有JavaScript都會(huì)在此循環(huán)中執(zhí)行,并且如果該代碼中發(fā)生了阻塞操作,則它將阻塞整個(gè)循環(huán),直到完成為止,否則將什么也不會(huì)發(fā)生。這是您經(jīng)常聽到的節(jié)點(diǎn)的典型單線程性質(zhì)。但是,這還不是全部。
通常使用C / C ++編寫的某些功能和模塊支持異步I / O。當(dāng)您調(diào)用這些函數(shù)和方法時(shí),它們?cè)趦?nèi)部管理將調(diào)用傳遞給工作線程。例如,當(dāng)您使用該fs
模塊請(qǐng)求文件時(shí),該fs
模塊將該調(diào)用傳遞給工作線程,該工作線程等待其響應(yīng),然后將其呈現(xiàn)回事件循環(huán),該循環(huán)在沒有它的情況下一直在進(jìn)行與此同時(shí)。所有這些都是從您(節(jié)點(diǎn)開發(fā)人員)那里抽象出來的,其中一些是通過使用libuv從模塊開發(fā)商那里抽象出來的。
正如Denis Dollfus在評(píng)論中指出的(從此答案到類似的問題),libuv用于實(shí)現(xiàn)異步I / O的策略并不總是線程池,特別是在http
模塊的情況下,似乎是另一種策略目前使用。對(duì)于我們這里的目的,最重要的是要注意如何實(shí)現(xiàn)異步上下文(通過使用libuv),并且libuv維護(hù)的線程池是該庫提供的實(shí)現(xiàn)異步的多種策略之一。
在一篇非常相關(guān)的切線上,這篇出色的文章對(duì)節(jié)點(diǎn)如何實(shí)現(xiàn)異步性以及一些相關(guān)的潛在問題以及如何處理這些問題進(jìn)行了更深入的分析。它的大部分內(nèi)容是在我上面寫的內(nèi)容基礎(chǔ)上擴(kuò)展的,但是另外指出:
您包含在項(xiàng)目中的任何使用本機(jī)C ++和libuv的外部模塊都可能使用線程池(請(qǐng)考慮:數(shù)據(jù)庫訪問)
libuv的默認(rèn)線程池大小為4,并使用隊(duì)列來管理對(duì)線程池的訪問-結(jié)果是,如果您同時(shí)有5個(gè)長時(shí)間運(yùn)行的數(shù)據(jù)庫查詢都在運(yùn)行,則其中一個(gè)(以及任何其他異步查詢)依賴于線程池的操作)將等待查詢結(jié)束,甚至無法開始
您可以通過
UV_THREADPOOL_SIZE
環(huán)境變量增加線程池的大小來緩解這種情況,只要您在需要并創(chuàng)建線程池之前就這樣做即可:process.env.UV_THREADPOOL_SIZE = 10;
如果要在節(jié)點(diǎn)中使用傳統(tǒng)的多處理或多線程,則可以通過內(nèi)置cluster
模塊或上述其他各種模塊來獲取webworker-threads
,也可以通過實(shí)現(xiàn)某種方式將工作分塊并手動(dòng)使用setTimeout
或進(jìn)行偽造setImmediate
或process.nextTick
暫停您的工作并在以后的循環(huán)中繼續(xù)進(jìn)行,以完成其他過程(但不建議這樣做)。
請(qǐng)注意,如果您使用javascript編寫長時(shí)間運(yùn)行/阻止的代碼,則可能是在犯錯(cuò)誤。其他語言將更有效地執(zhí)行。

TA貢獻(xiàn)1840條經(jīng)驗(yàn) 獲得超5個(gè)贊
這種誤解僅僅是搶先式多任務(wù)處理與協(xié)作式多任務(wù)處理之間的區(qū)別...
睡眠會(huì)關(guān)閉整個(gè)狂歡節(jié),因?yàn)樗杏螛吩O(shè)施實(shí)際上只有一條路線,而您關(guān)上了大門。將其視為“ JS解釋器和其他一些東西”,而忽略線程...對(duì)于您來說,只有一個(gè)線程,...
...所以不要阻止它。
- 3 回答
- 0 關(guān)注
- 1219 瀏覽
添加回答
舉報(bào)