回答
理解节点和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