2

私は私が従っている特定のロック順序を持っています。現在順次実行されているいくつかのタスクを実行するためのスレッドプールを作成しています。

ロックの順序は、プール->キュー->ジョブです。

ただし、ジョブの状態を確認するためにジョブをロックしてから、キューをロックしてジョブをあるキューから別のキューに移動する必要がある場合があります。したがって、ロックの順序に従うために、私はこれを取得します:

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

キューでtry-lockを実行できると思います。成功した場合は、両方のロックがあり、続行できます。失敗した場合、他の誰かがすでにキューロックを持っています。彼があなたのジョブロックを待っているかどうかわからないため、キューでブロッキングロックを実行する前に、まずジョブでロック解除を実行する必要があります。そうしないと、デッドロックが発生する可能性があります。

次のコードがデッドロックすることはないと思います。

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が成功したかどうかに応じて、キューとジョブのロックを解除する順序が異なる場合があります(成功した場合は順序が正しい、そうでない場合は間違っています)が、デッドロックは発生しないと思います。

于 2013-01-14T18:53:18.110 に答える