gpt4 book ai didi

node.js - node.js 代码会导致竞争条件吗?

转载 作者:IT老高 更新时间:2023-10-28 22:08:55 25 4
gpt4 key购买 nike

根据我的阅读,当不同的线程尝试更改共享变量时会出现竞争条件,这可能会导致这些线程的任何串行执行顺序都不可能出现的值。

但是 node.js 中的代码在单线程中运行,那么,这是否意味着用 node.js 编写的代码没有竞争条件?

最佳答案

是的,竞争条件(在共享资源的意义上由于事件的顺序而具有不一致的值)仍然可能发生在任何有可能导致其他代码运行的暂停点的地方(在任何一行处都有线程),以这段完全是单线程的异步代码为例:

var accountBalance = 0;

async function getAccountBalance() {
// Suppose this was asynchronously from a database or something
return accountBalance;
};

async function setAccountBalance(value) {
// Suppose this was asynchronously from a database or something
accountBalance = value;
};

async function increment(value, incr) {
return value + incr;
};

async function add$50() {
var balance, newBalance;
balance = await getAccountBalance();
newBalance = await increment(balance, 50);
await setAccountBalance(newBalance);
};

async function main() {
var transaction1, transaction2;
transaction1 = add$50();
transaction2 = add$50();
await transaction1;
await transaction2;
console.log('$' + await getAccountBalance());
// Can print either $50 or $100
// which it prints is dependent on what order
// things arrived on the message queue, for this very simple
// dummy implementation it actually prints $50 because
// all values are added to the message queue immediately
// so it actually alternates between the two async functions
};

main();

此代码在每个等待处都有暂停点,因此可能会在错误的时间在两个函数之间进行上下文切换,产生“$50”而不是预期的“$100”,这与维基百科的竞赛条件示例基本相同在线程中,但有明确的暂停/重新进入点。

就像线程一样,尽管您可以使用锁(又名互斥锁)之类的东西来解决此类竞争条件。所以我们可以像线程一样防止上述竞争条件:

var accountBalance = 0;

class Lock {
constructor() {
this._locked = false;
this._waiting = [];
}

lock() {
var unlock = () => {
var nextResolve;
if (this._waiting.length > 0) {
nextResolve = this._waiting.pop(0);
nextResolve(unlock);
} else {
this._locked = false;
}
};
if (this._locked) {
return new Promise((resolve) => {
this._waiting.push(resolve);
});
} else {
this._locked = true;
return new Promise((resolve) => {
resolve(unlock);
});
}
}
}

var account = new Lock();

async function getAccountBalance() {
// Suppose this was asynchronously from a database or something
return accountBalance;
};

async function setAccountBalance(value) {
// Suppose this was asynchronously from a database or something
accountBalance = value;
};

async function increment(value, incr) {
return value + incr;
};

async function add$50() {
var unlock, balance, newBalance;

unlock = await account.lock();

balance = await getAccountBalance();
newBalance = await increment(balance, 50);
await setAccountBalance(newBalance);

await unlock();
};

async function main() {
var transaction1, transaction2;
transaction1 = add$50();
transaction2 = add$50();
await transaction1;
await transaction2;
console.log('$' + await getAccountBalance()); // Now will always be $100 regardless
};

main();

关于node.js - node.js 代码会导致竞争条件吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21438207/

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