2011-03-01 48 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