节点中的哪些操作是线程安全的?

时间:2012-04-04 23:36:36

标签: node.js

我正在使用this approach将数据存储在托管http服务器的全局数组中,其中某些请求将操纵全局数组。

我有点担心遇到某些操作的线程问题 - 主要是pushsplice。我想如果一个请求让我迭代数组并根据条件删除项目,而另一个请求让我在数组上调用.push(),我将遇到问题。谁能证实这一点?

我主要使用C#编写,即使是简单的增量也不是线程安全的(启动25个执行i ++的线程,并不能保证i == 25毕竟说完了)。

更新

我写了5个例子来证明我在说什么。测试1和测试3工作正常。测试2失败,因为...通常会被称为线程问题(无论它们是否是实际的CPU线程)。测试4和5,当并行运行时似乎工作(意味着它们没有像测试2那样的碰撞问题)。

http://pastebin.com/HcJHTDFY

我正在使用ApacheBench进行测试,发出1000个并行请求。

这让我相信测试1和测试3工作正常,因为nodejs并不会并行执行app.get('/test3'...)回调并行的<{1}}回调实例 javascript函数(阻塞? )。一旦实现了setInterval / setTimeout,它就会释放nodejs来执行另一个回调实例(非阻塞?)。

我真的只是想了解non-blocking I/O model到底意味着什么。这是否意味着“嘿,如果你需要非阻塞,可以用setTimeout和setInterval进行非阻塞,否则我们将阻止任何其他外层函数运行,直到我们耗尽我们正在使用的函数” ?我觉得有必要知道这一点,这样我就不会觉得我可以实现像/ test2这样的东西并且完全安全。

此外,如果我尝试使用回调进行非阻塞,我是否真的应该调用setTimeout(code, 1)?或者有更好的方法吗?

2 个答案:

答案 0 :(得分:16)

所有都是线程安全的。

没有线程,JavaScript是单线程的,两个javascript语句不可能同时运行。

顺便说一下,你不应该使用全局变量因为全局变量是邪恶的

修改

测试2失败,因为您正在使用异步回调,这意味着控制返回到节点,它可以处理更多请求。这会产生竞争条件。

在节点中,任何非异步块。您拥有的唯一异步事项是setTimeout / setInterval / process.nextTick和任何异步IO操作。

不应该手动使计算不同步。人们应该避免做太多计算。

我写了一篇关于What it means to be non-blocking

的文章

答案 1 :(得分:-5)

Raynos大多是正确的。但仅仅因为JavaScript是单线程并不意味着你可以让你的警卫失望。你仍然需要了解线程。说明这一点的一个很好的例子是socket.io如何维护与不同客户端的连接,并且仍然能够跟踪这些客户端。

JavaScript的函数式编程部分通过变量绑定工作(如......很多)。不了解线程会让您错误地认为您的变量是正确绑定的。就像socket.io例子一样,你怎么能确定你得到的连接是你认为你得到的客户?如果引用绑定出错并且连接实际引用了不同的客户端怎么办?

这是你需要注意的事情类型。