回答
理解節點和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代碼運行時只有一個線程。
只有一個線程(事件循環),並且除非執行I/O之類的異步操作,否則不會中斷代碼。您不能執行任何並行代碼。因此ii ++是原子。
如果你解決了灰色地帶,本來會很好。比如,這個怎麼樣:dosomething(); doanotherthing(); ??? – 2011-03-02 20:48:37
@Michael沒有灰色地帶。 doanotherthing()總是在dosomething()之後執行,而不能在兩者之間切換控制(除dosomething()引發異常之外)。另請參閱@Matt的答案,更詳細地解釋了這一點。 – alienhard 2011-03-03 07:46:18
灰色區域是兩個函數調用是順序的,除非它們執行I/O,並且在使用第三方代碼時並不總是清楚。 – 2011-03-03 08:43:03
一篇很好的文章解釋了在node.js中是什麼和不是異步的是Understanding the node.js Event Loop。如果你能理解你將能夠確定你的應用程序在哪裏有異步行爲,哪些不是。通過理解這一點,您可以在需要時明確編寫順序代碼。 EventEmitters是關鍵。
單線程與node.js的高性能和可擴展性相呼應,因此請看這article from Yahoo on Multicore。
- 1. Erlang併發模型
- 2. Nodejs包括模型
- 3. NodeJS中的大型數組迭代併發送消息
- 4. 併發模型:Erlang vs Clojure
- 5. 將觸發器合併到模型中
- 6. 限制併發操作nodejs
- 7. Nodejs文件流併發
- 8. Nodejs Mongoose - 未定義模型
- 9. Mongoose,Express,NodeJS更新模型
- 10. Akka作爲Clojure的併發模型
- 11. 的ActionScript 3(AS3)併發模型
- 12. 發送中的NodeJS
- 13. NodeJS和MongoDB堆棧的併發控制
- 14. nodejs:抱怨使用的模型
- 15. 模塊的NodeJS出口類型錯誤
- 16. 併發模型:Erlang,Elixir和Scala
- 17. Java內存模型和併發讀取
- 18. Actor併發模型和緩存
- 19. AngularJS請求模型創建另一個模型之前[NodeJS]
- 20. NodeJS中的請求轉發
- 21. 來自合併模型的NSManagedObjectModel中的跨模型關係?
- 22. NodeJS如何處理高併發請求?
- 23. AMQPlib nodejs消費者任務併發
- 24. nodejs並行回調設計模式
- 25. 鍊金術語言+ WKS模型+ NodeJs
- 26. 如何在nodejs中處理對API的併發訪問
- 27. NodeJS/GeddyJS:從模型中獲取數據的設置限制
- 28. put方法不更新數據庫nodejs中的模型
- 29. 在CRCW線程模型中實現併發寫入
- 30. 的NodeJS子模塊
對於你所關心的全部,node.js是單線程的。 – Raynos 2011-03-01 11:01:55
@Raynos:不完全。 Javascript在單線程上運行,但阻塞IO是在單獨的線程池上完成的。 「當然,在後端,有數據庫訪問和流程執行的線程和進程。」引用:http://blog.mixu.net/2011/02/01/understanding-the-node-js-event-loop/ – 2013-11-07 16:11:39
更正:對於所有**你**護理node.js是單線程的。 – 2015-03-26 00:38:55