2011-03-05 91 views
129

如果我理解正確的節點JS是不可阻擋的...所以不是等待從數據庫或其他過程中它轉移到別的東西,並檢查回來以後的響應。抓節點JS替代多線程

另外它是單線程的。

所有這一切意味着給定的節點JS進程可以完全有效地利用單個CPU內核,但它不會使用機器上的任何其他內核,因爲它一次不會使用多個內核。

當然這意味着其它CPU仍然可以通過其它方法對於像SQL數據庫或其他有意分開CPU重子程序,只要它們是單獨的過程中使用。

也是在那個節點JS過程中有一個無限循環或長時間運行的功能的情況下,直到無限循環或長時間運行的功能被停止(或整個過程中被殺),該過程不再以任何方式有用。

是這樣嗎?我的理解是否正確?

+2

「節點」 是_not_單線程。只有JS/V8引擎在單線程中運行。 NodeJS的libuv部分是多線程的。參見[是否NodeJS真的是單線程?](http://stackoverflow.com/questions/7018093/is-nodejs-really-single-threaded) – RaelB 2016-09-20 08:46:21

+1

掛接http://stackoverflow.com/q/17959663/632951 – Pacerier 2017-02-19 18:53:42

回答

84

差不多是正確的,是的。 node.js服務器有一個內部線程池,因此它可以執行阻塞操作並在事情完成時用回調或事件通知主線程。

所以我想它會限制使用另一個線程池的核心,例如,如果你做一個非阻塞文件系統讀取這可能是通過告訴線程池中的線程執行讀取和當它完成時設置一個回調,這意味着讀取可能發生在不同的線程/核心上,而主要的node.js程序正在做其他事情。

但從一個node.js的點,它完全單線程的,並不會直接使用一個以上的核心。

+2

我對Node.js仍然很陌​​生,並欣賞這裏的討論。我只想指出,假設非阻塞調用由線程阻塞調用支持可能不明智(不是@jcoder建議圍繞這些假設構建代碼)。在這種情況下,即使IO在具有阻塞調用的單獨線程上處理,該線程基本上仍會等待IO,因此它不會使用其他核心/ CPU。根據您使用的工具的強度進行編碼,不要過多擔心低級別細節(直到它們成爲問題)。 – wbyoung 2014-03-05 20:05:12

+0

所以我們可以使用前端的JavaScript代碼回調其他散文 – yussan 2016-05-27 03:51:01

35

是的,我會說你的理解完全正確。 This articlearchived)很好地解釋了這種設計背後的基本原理。這可能是最重要的一段:

Apache是​​多線程的:它爲每個請求(或進程,它依賴於conf)產生一個線程。隨着併發連接數量的增加以及需要更多線程來爲多個同時的客戶端服務,您可以看到這種開銷如何消耗內存。 Nginx和Node.js不是多線程的,因爲線程和進程會帶來沉重的內存成本。它們是單線程的,但是基於事件。這消除了數千個線程/進程通過處理單個線程中的多個連接而產生的開銷。

+0

文章是錯誤的。雖然存在多線程apache mpm,但它與幾乎所有日常使用的配置都不兼容。 Apache是​​多進程的,直到現在還沒有多線程,並且可能會永遠存在。我覺得它是災難性的,操縱術語的恰當含義只是一個很好的嘗試來隱藏問題,而不是解決它。 – peterh 2017-04-13 21:55:03

+1

@peterh你沒有道理。該文章是完全正確的,說明apache是​​多進程或多線程取決於配置。多處理器的情況在處理多個連接方面更糟,這是首先提到Apache的唯一原因。此外,最常用的PHP模塊全部都是多線程的。最後,雖然我不是apache專家,但我從其他文章中得到的印象是工人MPM實際上非常常用。 – 2017-04-17 13:22:42

+0

@MichaelBorgwardt是的,Apache可以是多線程的,也可以是多進程的,我沒有否認。但是php與多進程配置不兼容,如果你是apache專家,你肯定會知道它。非常常用的php模塊不是多線程的。你的信息是錯誤的。我建議嘗試測試配置,你會看到。這是一個事實上的事情,無論是辯論,嘗試它,你會看到。 – peterh 2017-04-21 07:55:33

26

即使這是一個古老的線程,我想,我會一個想法,如何利用在Node.js的應用更是一個核心共享。正如Nuray Altin所說 - JXcore可以做到這一點。

簡單的例子:

var method = function() { 
    console.log("this is message from thread no", process.threadId); 
}; 

jxcore.tasks.runOnThread(0, method); 
jxcore.tasks.runOnThread(1, method); 

// this is message from thread no 1 
// this is message from thread no 0 

默認有兩個線程(你可以用jxcore.tasks.setThreadCount()改變它)

當然還有更多,您可以用任務做。文檔是here

關於這個問題的幾篇文章:

1

Node.js的是一個單線程應用程序,但它可以通過事件和回調的概念,支持併發。這裏是視頻Philip Roberts它解釋了事件循環如何在javascript中工作。

Click here to see the video

(相反WebAPIs的有在Node.js的C++的API)

+2

這應該是一個評論 – Cherniv 2017-01-10 10:47:54