Node.js和Mutexes

时间:2011-03-30 03:53:08

标签: javascript node.js

我想知道Node.js中的数据访问是否需要互斥锁/锁。例如,假设我创建了一个简单的服务器。服务器提供了一些协议方法来添加和删除内部数组。我是否需要使用某种类型的互斥锁保护内部阵列?

我理解Javascript(因此Node.js)是单线程的。我不清楚如何处理事件。事件中断吗?如果是这种情况,我的应用程序可能正在读取数组,被中断以运行更改数组的事件回调,然后继续处理现在已被事件回调更改的数组。

4 个答案:

答案 0 :(得分:33)

有时锁和互斥锁确实是必要的,即使Node.js是单线程的。

假设您有两个必须具有相同内容但没有相同内容的文件被视为不一致状态。现在假设你需要在不阻塞服务器的情况下更改它们。如果你这样做:

fs.writeFile('file1', 'content', function (error) {
    if (error) {
        // ...
    } else {
        fs.writeFile('file2', 'content', function (error) {
            if (error) {
                // ...
            } else {
                // ready to continue
            }
        });
    }
});

当两个调用之间处于不一致状态时,同一个脚本中的另一个函数可能会读取这两个文件。

rwlock模块非常适合处理这些情况。

答案 1 :(得分:22)

  

我想知道Node.js中的数据访问是否需要互斥锁/锁。

都能跟得上!在没有其他代码运行的情况下处理事件,这意味着不存在争用,因为只有当前运行的代码才能访问该内部数组。作为节点单线程的副作用,长计算将阻止所有其他事件,直到计算完成。

  

我理解Javascript(因此Node.js)是单线程的。我不清楚如何处理事件。事件中断吗?

不,事件不会中断。例如,如果将while(true){}放入代码中,它将阻止执行任何其他代码,因为总会有另一个循环迭代要运行。

如果你有一个长时间运行的计算,最好使用process.nextTick,因为这样可以在没有其他任何东西运行时运行(我对此很模糊:下面的例子显示我可能是正确的,它可能不间断地运行。

如果您有任何其他问题,请随时访问#node.js并提出问题。另外,我让几个人看看这个,并确保我并非完全错误;)

var count = 0;

var numIterations = 100;
while(numIterations--) {
  process.nextTick(function() {
    count = count + 1;
  });
}

setTimeout(function() {

  console.log(count);

}, 2);

//
//=> 100
//

感谢#node.js的AAA_awright:)

答案 2 :(得分:0)

我一直在寻找节点互斥的解决方案。有时需要互斥锁 - 您可能正在运行节点应用程序的多个实例,并且可能希望确保只有其中一个实例正在执行某些特定操作。我能找到的所有解决方案要么不是跨进程,要么取决于redis。

所以我使用文件锁创建了自己的解决方案:https://github.com/Perennials/mutex-node

答案 3 :(得分:0)

对于许多后端实现,Mutexe绝对是必需的。考虑一个需要通过构造一个Promise链来保持异步执行的同步性的类。

let _ = new WeakMap();
class Foobar {
  constructor() {
    _.set(this, { pc : Promise.resolve() } );
  }
  doSomething(x) {
    return new Promise( (resolve,reject) => {
      _.get(this).pc = _.get(this).pc.then( () => {
        y = some value gotten asynchronously
        resolve(y);
      })
    })
  }
}

您如何确定不会因比赛条件悬而未决?令人沮丧的是,由于javascript本质上是异步的,因此节点没有使互斥体成为本机,将第三方模块带入进程空间始终存在安全风险。