3

クリティカルセクションがある場合は、それをロックする方法を実装する必要があります。私は次の変種を見ました:

while(lock)
{
    //do nothing
}
lock = true;
// code of critical section
lock = false;

while(lock)ただし、理論的には、複数のスレッドが実行でき(= falseであることを確認して確認)、1つの連続したブロックで実行されないためwhile(lock)、一緒にクリティカルセクションに入る可能性があるため、私はそれについて疑っています。lock = true;私が間違っている?または、これは確かに安全ではない方法ですか?

4

3 に答える 3

5

あなたは正しいです-それは安全ではありません。それ以上に言うことはありません。

編集:いいえ、実際には、この構成について言うことはそれほど多くありません。これはスピンロックではなく、スピンロックのようなものでもありません。スピンロックの場合、漠然と次のようなものが必要です。

// note: incomplete, not reentrant, not intended for real use
atomic_type spin_lock = 0;

// enter the spin lock:
int prev_value;

while ((prev_value = test_and_set(&spin_lock, 1)) != 0 || spin_lock != 1)
    ;
// code of critical section

// release the spin lock:
test_and_set(&spin_lock, 0);

ここで重要なのは、スピンロックに入るには、前の値を取得し、新しい値をアトミックに設定する必要があるということです。次に、ロックへの書き込みによって「所有されていない」ステータスから「所有されている」ステータスに変更されたことを確認する必要があります。

于 2012-05-21T17:51:14.693 に答える
3

これは「ほぼ安全」です。つまり、まったく安全ではありません。欠けているのは、まさにあなたが見ているものです。複数のスレッドがlock == falseクリティカルセクションを見て入る可能性があります。これにはアトミック操作が必要です。これはハードウェアでサポートされている必要があります。これは、実行の1つのスレッドのみがロックを取得できることを保証する方法です。

とは言うものの、あなたが書いているシステムが相互排除の失敗に耐えることができ、通常は時折の失敗(おそらくロギングや時折のマングルエントリが必ずしも完全な失敗を引き起こさない何か)でうまくいくなら、このパターンは「ソート」することができます仕事...

于 2012-05-21T17:56:59.207 に答える
0

実装しようとしているのはスピンロックと呼ばれます。新しいC標準であるC11は、atomic_flagそのように使用できると呼ばれるプリミティブデータ型を実装しています。最近のほとんどすべてのハードウェアがそれをサポートしていますが、残念ながら、ほとんどのコンパイラは、構文のレベルでそれをサポートするためにまだ正確にそこにありませんが、独自の拡張機能を持っています。たとえば、gccには組み込みが__sync_lock_test_and_setあり__sync_lock_releaseます。

于 2012-05-21T18:22:08.607 に答える