gpt4 book ai didi

node.js:如何锁定/同步代码块?

转载 作者:搜寻专家 更新时间:2023-10-31 23:34:06 24 4
gpt4 key购买 nike

让我们看一下简单的代码片段:

var express = require('express');
var app = express();
var counter = 0;

app.get('/', function (req, res) {
// LOCK
counter++;
// UNLOCK
res.send('hello world')
})

假设 app.get(...) 被调用了很多次,正如你所理解的,我不希望行 counter++由两个不同的线程同时执行。

因此,我想锁定这一行,只有一个线程可以访问这一行。我的问题是如何在 node.js 中做到这一点?

我知道有一个锁包:https://www.npmjs.com/package/locks,但我想知道是否有“native "无需外部库的方式。

最佳答案

I don't want the line counter++ to be executed concurrently by the two different threads

这在仅使用常规 Javascript 编码的 node.js 中是不可能发生的。

node.js 是单线程和事件驱动的,因此一次只能运行一段 Javascript 代码来访问该变量。您不必担心多线程系统的典型抢占式并发问题。

也就是说,如果您使用异步代码,您仍然会在 node.js 中遇到并发问题,因为 node.js 异步模型将控制权返回给系统以处理下一个事件,并且异步回调会在未来的某个事件上被调用.但是,并发问题是非先发制人的,因此您可以完全控制它们何时会发生。

如果您在 app.get() 路由处理程序中向我们展示您的实际代码,那么我们可以更具体地建议您是否存在并发问题。而且,如果您这样做,我们可以就如何最好地处理它提出建议。

线程池中的线程都是在后台运行的原生代码。它们仅通过在事件队列中对事件进行排队来触发实际的 Javascript 运行。所以,因为所有运行的 Javascript 都是通过事件队列序列化的,所以你一次只能得到一个运行的 Javascript 片段。事件队列的基本方案是解释器运行一段 Javascript,直到它把控制权交还给系统。此时,解释器会查看事件队列,如果有事件在等待,它会拉出该事件并调用与该事件关联的回调。同时,如果有 native 代码在后台运行,当它完成时,它会向事件队列添加一个事件。在当前 Javascript 将控制权返回给系统之前,该事件不会被处理,然后它可以从事件队列中获取下一个事件。因此,正是这个事件队列一次只序列化运行一段 Javascript。

编辑:Nodejs 现在确实有 WorkerThreads,它启用了独立的 Javascript 线程,但每个线程都有自己的堆和变量,因此一个线程的变量不能直接从另一个线程访问。您可以配置两个 WorkerThreads 都可以访问的共享内存,但这不是直接变量,而是内存块,如果您想使用共享内存,那么您确实需要编写自己的同步方法以确保您正在原子访问变量。您在问题中显示的代码没有使用任何这些,因此对 counter 变量的访问已经是原子的,并且不能同时被任何其他 Javascript 访问,即使您使用的是 WorkerThreads。

关于node.js:如何锁定/同步代码块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50981237/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com