2

我有一个特定的锁定顺序,我正在遵循。我正在编写一个线程池来执行一些当前按顺序完成的任务。

锁定顺序为 pool->queue->job。

但是,有时我需要锁定作业以检查作业的状态,然后锁定队列以将作业从一个队列移动到另一个队列。所以,按照锁定顺序,我得到了这个:

lock job

if (job->state == CANCELED) {
unlock job
lock queue
lock job
// check that it is still canceled and do work
}

我的问题是,是否有没有解锁/锁定工作的替代方法?当必须保留锁定顺序并且需要“更高”的锁定时,如何处理?

4

1 回答 1

2

我认为您可以在队列上进行尝试锁定。如果成功,则您拥有两个锁并且可以继续。如果失败,则其他人已经拥有队列锁,并且由于您不知道他是否正在等待您的作业锁,因此您必须先对作业进行解锁,然后才能对队列执行阻塞锁,否则您可能会死锁。

我认为以下代码永远不会死锁:

lock(job);
if (job->state == CANCELED) {
    if (!tryLock(queue)) {
        // Cannot lock queue; must avoid dead lock
        unlock(job);
        lock(queue); // This one might block now
        lock(job);
    }
    if (job->state == CANCELED) {
         // Do work
    }
    unlock(queue);
}
unlock(job);

您可能以不同的锁定顺序解锁队列和作业,这取决于尝试锁定是否成功(如果成功,顺序正确,否则错误),但我仍然认为它永远不会死锁。

于 2013-01-14T18:53:18.110 回答