由于未兑现承诺而导致程序挂起的期限

Term for program hanging due to unsatisfied promise

一个程序有一个逻辑错误,导致承诺永远不会被满足(或者如果你来自 Java 土地,你的 Future is never Completed)。结果,程序挂了。

似乎这种情况可以推广到生产者-消费者,其中生产者 forgets/loses 东西。

你怎么称呼这种情况?有没有术语或短语来描述它?


我不觉得死锁是对的,因为我无法识别循环依赖(necessary conditions for deadlock之一)。 Livelock 似乎也不对,因为线程没有争用资源——它们只是无事可做。

我认为有些人确实将此称为死锁。如果有人能让我相信在这种情况下实际上满足了所有 conditions for deadlock,那么我认为这是一个令人满意的答案。

这称为活跃度问题

有几种不同的 活性 问题,可能是由于代码中的不同问题引起的。

图片取自here

死锁

如果存在资源争用并且两个或多个承诺持有另一个承诺需要进行的资源并且不释放它们。当存在 locking 时会发生这种情况。例如,promise 返回函数 P1 持有资源 A 的 mutex,P2 持有资源 B 的互斥锁。为了进行,P1 需要为 A 获取锁,为了进行 P2 需要为 A 获取锁- 所以既不能进步也不能释放锁。程序停止。

var aPromise = Promise.resolve(); // empty promise
var bPromise = Promise.resolve(); // empty promise
function lockedResourceA(user){
   return aPromise = aPromise.then(user);
}
function lockedResourceB(user){
   return bPromise = bPromise.then(user);
}

现在,让我们陷入僵局:

lockedResourceA(function(a){
    return lockedResourceB(b){
        // do computation
    });
});

lockedResourceB(function(a){
    return lockedResourceA(b){
        // do computation
    });
});

这里有可能计算永远不会进行。

活锁

An infinite loop prevents this incarnation of a vat from ever again making progress, just as it would prevent a conventional thread from making progress. As with conventional threads, it does not prevent other vats (threads) from making progress. Unfortunately, since each E object is in only one vat, livelocking a vat does lock up all objects within a vat. (This would be analogous to livelocking a thread that holds a synchronized lock on several objects.)

source

这类似于死锁,只不过不是承诺说“卡住”,而是每个尝试产生下一个资源。例如,在上面的示例中想象一下,promise 返回函数不关心它们首先获得哪个资源 - 因此 P1 和 P2 每次都尝试产生一个资源,因此它们每个都获得一个交替资源并且都没有完成,因为在每一轮其中只有一项。

数据锁

这是一个没有底线的递归数据定义 - 例如一个依赖于自身的承诺或多个递归地相互依赖以实现的承诺。

例如:

var p = Promise.resolve().then(function(){ 
    return p; // datalock
});

Here is a full wrap up of this problem

网格锁定

Technically, this looks like a classic deadlock, but it's caused specifically by lack of outgoing buffers. The distinction between deadlock and gridlock? If more buffer space would have caused you not to have locked up yet, then it's gridlock rather than deadlock.

source

当您在 promise 队列中缓冲并且缓冲区不足 space 阻碍了进度时,就会发生这种情况。这与流背压问题非常相关。

信号丢失

当您做出承诺但没有兑现或违背时,就会发生这种情况。

An example, due to Mark Seaborn (thanks!): If you have a when-catch "waiting" (posted as a callback) for a promise to be resolved, but in the code that's supposed to resolve it, you forget to call resolve in all applicable cases. Of course, actual lost signal bugs may be arbitrarily more complicated than this.

source

例如:

var p = new Promise(function(resolve, reject){
    // never call resolve
});
p.then(function(){
    // never runs
});

这是 Mark S. Miller 的 an excellent summary on the topic