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

Lan*_*don 12 node.js

我正在使用这种方法将数据存储在托管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不会并行执行并行 javascript函数中的多个app.get('/test3'...)回调实例(阻塞?).一旦实现了setInterval/setTimeout,它就会释放nodejs来执行另一个回调实例(非阻塞?).

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

另外如果我试图用我的回调进行非阻塞,我真的应该打电话setTimeout(code, 1)吗?或者,还有更好的方法?

Ray*_*nos 16

一切都是线程安全的.

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

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

编辑:

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

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

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

我写了一篇关于非阻塞意味着什么的文章

  • @Langdon你不在乎,你永远不会看到线程.这就像问"SQL线程安全吗?".尽管SQL引擎实现在某个地方使用了几层线程,但您从未看到它们,也不关心它们,它们只是实现细节. (4认同)
  • 我相信答案有点误导。即使它是单线程,但这并不意味着它是线程安全的,因为您仍然可能遇到竞争条件,并且拥有线程并不意味着同时运行两个语句,除非您有多核处理器。人们期望线程安全的代码没有竞争条件。用户级线程和内核线程之间也有区别。您可以在没有编程语言直接支持的情况下实现用户级线程。 (2认同)