【问题标题】:race condition issue in node?节点中的竞争条件问题?
【发布时间】:2014-08-07 00:00:58
【问题描述】:

人们说像 Javascript 这样的单线程语言不能解决这个问题。然而,nodejs 提供了cluster 来分叉多个worker。这会导致race condition 问题吗?

另外,我有一个例子有时会引起我的困惑:

ALLSESSIONS = {};
//session id saved in cookie
ALLSESSIONS[sessionid] = 'somevalue';

var SESSION = ALLSESSIONS[sessionid];
... do stuff for sometimes
console.log(SESSION);

恐怕当当前请求还在运行时另一个请求到达节点时,它可能会用自己的会话ID覆盖SESSION变量,那么当前请求的结果是undetermined

这会发生在节点中吗?

【问题讨论】:

  • This question 回答了您关于比赛条件的一些问题。是的,如果您以这种方式编写程序,您可能有两个单独的请求发生冲突,但在大多数情况下,您的请求不应写入全局变量。不过,这不是cluster 引入的问题,错误地编写异步代码时也会发生这种情况。如果您有任何希望我们调试的真实代码,请向我们展示,因为您的示例描述性不强。

标签: node.js race-condition


【解决方案1】:

当另一个请求到达节点而当前请求仍在运行时,它不会用自己的会话变量覆盖。

集群允许您拥有多个工作人员,这些工作人员将彼此分开。这意味着如果您的 ALLSESSIONS 变量的范围仅限于单个工作人员,那么它实际上将只包含给定工作人员的会话信息。您需要将 ALLSESSIONS 变量限定在应用程序(分叉前)级别,以便在工作人员之间共享它。

但是,将会话信息保存在内存中可能不是一个好主意!如果您的工作线程或应用程序线程崩溃,那么您就丢失了会话数据。使用某种持久性存储可能会更好。

一般来说,如果您有一个全局范围的变量被写入多个请求线程并从多个请求线程中读取,则可能会发生竞争条件。

【讨论】:

  • 从你的角度来看,如果我将会话存储在文件中,SESSION 变量仍然是全局范围,因为所有工作人员都可以访问系统中的任何文件。我想对了吗?
  • 是的 - 如果您要将会话存储在文件中,SESSION 变量将基本上是全局范围。所有工作人员都将访问这些文件 - 如果您不小心“阻塞”这些文件的 I/O,它可能会导致竞争条件。
  • 感谢您的回复。顺便说一句,您对节点中的共享数据(例如会话)有何建议?
  • 我使用过 mongodb 和 postgres 会话存储,运气不错。在运行节点的服务器上安装 mongodb 通常非常简单,社区提供了一些软件包,使其与 express 框架一起使用非常简单。见connect-mongo
猜你喜欢
  • 1970-01-01
  • 2023-01-30
  • 2013-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多