たとえば、複数のスレッドT1、T2、T3およびT4があります。 T1はリソースAを、T2はリソースBを、T3はリソースA、BおよびCを、T4はリソースBおよびCをそれぞれ有する。複数のロックを取得するときにデッドロックを解決する
T1が来たら、それはAをロックして何らかの作業を行う。
T2が来たら、Bでロックして何らかの作業をします。
次はT3ですが、Cでロックされていますが、まだAが取得されていないため、Aで待機していません。
最後に、ここでT4はB(まだBが取得されていないためCではない)を待ちます。 T2は、Bのロックを終了し、解放した場合さて、T4がBにロックすることが起床され
for all resources needed { // in case of T3, they are A and B
acquire lock on resource; // acquiring lock one after one
}
しかし、それはまだCに待つ必要があるだから今T4が成り立つ:
擬似コードは次のようですBを待ち、Cを待ちます。
T1が終了してAのロックを解除し、T3がロックされてAをロックすると、デッドロックが発生しますが、T3はAとCを保持し、Bを待機します私はT3とT4を無限に待っています。これを解決するには
、私の擬似コードのように変更:
while not all resource locks obtained { // in case of T3, they are A and B
try to lock on resource; // immediate return success or fail
if fail, release all unsecured locks; // in case of T3, C is secured,
// so only A and B may be released,
// in case of T4, both B and C may be released
}
変更されたコードは動作しますが、私のテストでは、私はT3とT4は常にロックをチェックして、全体的なプログラムは、しばらくの遅くによる走った見ることができましたループ。
は、それから私は、コードに小さな変更を加えた:while not all resource locks obtained {
try for 1 second to lock on resource; // return after 1 second if fail
if fail, release all unsecured locks;
}
わずかな変化はロックのチェックがそれほど頻繁に行われ、プログラムが速く、以前よりも走りました。
私は現時点でのものが嫌いです。最適ではないように見えますし、効果が望みの結果に達する前にランダムです。上記のデッドロック状況を解決するための良い方法はありますか?デッドロックを防止
「非効率的」はここではほとんど言いません。 – EJP
@EJPそれは、間違っているわけではありません。それは意図的に過言ではありません。 :-) –
スループットがゼロの手法は、効率的でも非効率的でもありません。間違っています。あなたが一種の冗談を作ろうとしているなら、あなたは成功していません。 – EJP