3

私はマルチスレッドを研究しており、セマフォ相互排除の概念を理解しようとしています。私がオンラインで見つけた例のほとんどは、セマフォまたはミューテックスを実装するためにある種のライブラリ (例: pthread) を使用していますが、クリティカル セクションを確立する単純なセマフォの実装にもっと興味があります。メモリの領域。

このタスクには、ミューテックス (用語を正しく理解していればバイナリ セマフォとも呼ばれます) が必要になると思います。セマフォがコードのセクションを単一のスレッドに「ロック」することで競合状態を防ぐ方法はわかりますが、セマフォ自体で競合状態が発生するのを防ぐものは何ですか?

ロックを追跡するためにint値を保持するバイナリセマフォを想像します。

Semaphore
---------
int lock = 1;

unsigned P(void){
    if(lock > 0){
        lock--;
        return 0; /* success */
    }
    return 1; /* fail */
}

void V(void){
    lock++;
}

2 つのスレッドが同時に関数を呼び出し、両方が同時にチェックにP到達し、条件をtrueとして評価するとします。これにより、両方のスレッドが同時にメモリの同じ領域へのアクセスを許可される競合状態が作成されます。if(lock > 0)

では、セマフォの実際の実装でこの競合状態が発生するのを妨げているのは何でしょうか?

4

3 に答える 3

4

ロックと解放semaphores、および/または操作mutexesとして発生しatomicます。これは、CPU を現在のプロセスから取り消すことができないことを意味します。これにより、mutex ロックが開始されるとすぐに (単一または少数の CPU 命令 (マイクロコード) で構成されます)、プロセスはロック/解放が完了するまで CPU を保持します。スレッド化を実装するさまざまな方法もあり、CPU (カーネル空間) による直接サポートか、ユーザー空間
のライブラリ (など) によるサポートのいずれかです。pthreads


OSDev.orgから

アトミック操作とは、操作中に読み取られた、または変更された状態を他のプロセスが読み取ったり変更したりすることなく、常に実行される操作です。これは単一のステップとして効果的に実行され、同期と同期を必要とせずに共有データを更新するアルゴリズムの両方で、複数の独立したプロセスを処理する多くのアルゴリズムで重要な品質です。


こちらも原子性に関する素晴らしい記事です (Delphi ではありますが)。

于 2013-04-23T13:16:08.797 に答える
3

ほとんどのロッキング プリミティブを実装する最も一般的な (絶対に唯一というわけではありませんが) 方法は、compare-and-set 命令です。通常の移動命令は、メモリ位置の値を要求した値に設定するだけですが、比較セット命令は、「メモリ位置の値が Y の場合にのみ、このメモリ位置を値 X にアトミックに設定し、次に操作が成功したかどうかに応じてフラグを設定します。」キーワード「アトミック」は、CPU がハードウェアでその操作を妨げるものがないことを確認できることです。

比較とスワップ命令を使用すると、例は次のPように実装できます。

int oldlock;
retry:
oldlock = lock;
if (oldlock > 0) {
    if (compare_and_swap(&lock, oldlock, oldlock - 1))
        goto retry;
    return 0;
}
return 1;

もちろん、現実はそれよりもはるかに複雑ですが、compare-and-set は理解しやすく説明しやすく、他のすべてのロック プリミティブを (ほとんど?) 実装できるという優れた特性を備えています。

ここにウィキペディアの記事があります。

于 2013-04-23T13:29:03.127 に答える