不完全是严肃的问题,更像是淋浴的想法:JavaScript的await
关键字应该允许一些在普通的“并发语言”中感觉非常像互斥锁的东西。
function Mutex() {
var self = this; // still unsure about how "this" is captured
var mtx = new Promise(t => t()); // fulfilled promise ≡ unlocked mutex
this.lock = async function() {
await mtx;
mtx = new Promise(t => {
self.unlock = () => t();
});
}
}
// Lock
await mutex.lock();
// Unlock
mutex.unlock();
这是一个正确的实现吗(除了正确的错误处理之外)?还有......我可以使用C++-RAII样式的锁保护吗?
3条答案
按热度按时间shstlldc1#
您的实现允许与请求锁的数量一样多的使用者获得锁;对
lock
的每个调用都等待一个承诺:您需要实现一个承诺队列,为每个锁请求创建一个新队列。
旁注:
new Promise(t => t())
可以更简单、更习惯地写成Promise.resolve()
:-)self
;arrow函数 * 关闭 * 创建它们的this
(就像关闭变量一样)unlock
作为锁承诺的解析值可能是有意义的,因此只有获得锁的代码才能释放它大概是这样的
示例:
一个二个一个一个
z31licg02#
这是正确的实现吗?
不,如果两个任务(我不能说是“线程”)试图在
mutex.lock()
当前被锁定时执行它,它们将同时获得锁,我怀疑这是您想要的。JS中的互斥锁实际上只是一个布尔标志--你可以检查它,在获取锁时设置它,在释放锁时清除它。在检查和获取之间没有特殊的竞争条件处理,因为你可以在单线程JS中同步进行,没有任何其他线程的干扰。
然而,您似乎正在寻找的是一个 * 队列 *,即您可以安排自己获得锁,并在前一个锁被释放时得到通知(通过承诺)的东西。
我会用
演示:
7ivaypg93#
我建议使用async-mutex这样的库: