12

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

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

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

4

2 回答 2

18

都是线程安全的。

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

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

编辑:

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

在节点中,任何不是异步块的东西。您拥有的唯一异步内容是 setTimeout/setInterval/process.nextTick 和任何异步 IO 操作。

不应该手动使计算异步。一个人应该避免做太多的计算。

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

于 2012-04-04T23:39:47.867 回答
-5

Raynos 基本上是正确的。但是仅仅因为 JavaScript 是单线程的并不意味着你可以放松警惕。您仍然需要了解线程。一个很好的例子来说明这一点,socket.io 如何与不同的客户端保持连接,并且仍然能够跟踪这些客户端。

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

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

于 2012-04-05T00:29:23.603 回答