我有一个特定的锁定顺序,我正在关注。我正在编写一个线程池来执行当前按顺序完成的一些任务。
锁定顺序是pool-> queue-> job。
但是,有时我需要锁定作业以检查作业的状态,然后锁定队列以将作业从一个队列移动到另一个队列。所以,为了遵循锁定顺序,我得到了这个:
lock job
if (job->state == CANCELED) {
unlock job
lock queue
lock job
// check that it is still canceled and do work
}
我的问题是,是否有另一种方法可以做到这一点,没有解锁/锁定工作?当必须保留锁定顺序并且需要锁定“更高”时,如何处理?
答案 0 :(得分: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);
您可能正在以不同的锁定顺序解锁队列和作业,具体取决于try-lock是否成功(如果成功则顺序正确,否则会出错),但我仍然认为它不会死锁。