2011-03-01 50 views
28

有誰知道nodejs中的內存和線程模型是什麼?nodejs中的併發模型

特別是ii++原子?它的行爲好像iivolatile在Java 1.5中,在Java 1.4中,在C中,還是根本沒有?

+2

對於你所關心的全部,node.js是單線程的。 – Raynos 2011-03-01 11:01:55

+2

@Raynos:不完全。 Javascript在單線程上運行,但阻塞IO是在單獨的線程池上完成的。 「當然,在後端,有數據庫訪問和流程執行的線程和進程。」引用:http://blog.mixu.net/2011/02/01/understanding-the-node-js-event-loop/ – 2013-11-07 16:11:39

+1

更正:對於所有**你**護理node.js是單線程的。 – 2015-03-26 00:38:55

回答

37

理解節點和V8如何交互很有用。節點處理等待來自操作系統的I/O或定時器。當節點從I/O或定時器喚醒時,它通常會調用一些JavaScript回調。當節點運行這些回調時,控制傳遞到V8,直到V8返回節點。

所以,如果你做var ii = 1; ii++;,你永遠不會發現ii是除了2以外的任何東西。所有的JavaScript運行直到完成,然後控制傳回給節點。如果你做doSomething(); doSomething();,它總是會運行doSomething兩次,並且直到doSomething的第二次調用返回時纔會返回到節點的事件循環。這意味着你可以完全從一個簡單的錯誤鎖定節點是這樣的:

for (var i=0 ; i >= 0 ; i++) {} 

它沒有母校多少I/O回調您已註冊,設置計時器走下車,或插座等待被讀取。在V8從無限循環返回之前,節點不再工作。

這是編程節點如此之好的一部分。你永遠不必擔心鎖定。沒有比賽條件或關鍵部分。 JavaScript代碼運行時只有一個線程。

+2

我有一個愚蠢的時刻,一秒鐘不知道爲什麼這是一個無限循環。對於像我這樣慢的人,請記住for循環中的第二個條件是_continuation_的條件,而不是終止。即終止循環的標準是「for(var i = 0; i <0; i ++){}」 – everybody 2015-01-16 14:13:07

+3

它真的是無限的嗎?我會不會在某個時候環繞並變得消極? – stu 2015-02-06 13:39:02

+3

試試這個:'9007199254740992 + 1' – maletor 2015-03-18 17:12:08

12

只有一個線程(事件循環),並且除非執行I/O之類的異步操作,否則不會中斷代碼。您不能執行任何並行代碼。因此ii ++是原子

+0

如果你解決了灰色地帶,本來會很好。比如,這個怎麼樣:dosomething(); doanotherthing(); ??? – 2011-03-02 20:48:37

+0

@Michael沒有灰色地帶。 doanotherthing()總是在dosomething()之後執行,而不能在兩者之間切換控制(除dosomething()引發異常之外)。另請參閱@Matt的答案,更詳細地解釋了這一點。 – alienhard 2011-03-03 07:46:18

+0

灰色區域是兩個函數調用是順序的,除非它們執行I/O,並且在使用第三方代碼時並不總是清楚。 – 2011-03-03 08:43:03

4

一篇很好的文章解釋了在node.js中是什麼和不是異步的是Understanding the node.js Event Loop。如果你能理解你將能夠確定你的應用程序在哪裏有異步行爲,哪些不是。通過理解這一點,您可以在需要時明確編寫順序代碼。 EventEmitters是關鍵。

單線程與node.js的高性能和可擴展性相呼應,因此請看這article from Yahoo on Multicore