3

BeOS プログラマーだった頃、 Benoit Schillings によるこの記事を読み、「ベナフォア」を作成する方法を説明しました: アトミック変数を使用して、共通のミューテックスを取得/解放する必要を回避するクリティカル セクションを強制する方法 (競合なし) ケース。

私はそれがかなり賢いと思いました.atomic-increment/decrementをサポートするどのプラットフォームでも同じトリックを行うことができるようです.

一方、これは標準のミューテックス実装自体に簡単に含めることができるもののように見えます...その場合、私のプログラムでこのロジックを実装することは冗長であり、何の利点もありません.

最新のロック API (pthread_mutex_lock()/pthread_mutex_unlock() など) がこのトリックを内部的に使用しているかどうかを知っている人はいますか? もしそうでなければ、なぜですか?

4

2 に答える 2

2

あなたの記事が説明していることは、今日一般的に使用されています。ほとんどの場合、これは「クリティカル セクション」と呼ばれ、インターロックされた変数、一連のフラグ、および内部同期オブジェクト (記憶が正しければミューテックス) で構成されます。通常、競合がほとんどないシナリオでは、クリティカル セクションは、カーネル同期オブジェクトを使用せずに、完全にユーザー モードで実行されます。これにより、高速な実行が保証されます。競合が多い場合は、待機にカーネル オブジェクトが使用されます。これにより、タイム スライスが解放され、ターンアラウンドが高速化されます。

一般に、この時代に同期プリミティブを実装する意味はほとんどありません。オペレーティング システムには、さまざまなオブジェクトが付属しており、1 人のプログラマーが想像できるよりもはるかに幅広いシナリオで最適化およびテストされています。優れた同期メカニズムを発明、実装、テストするには文字通り何年もかかります。試すことに価値がないと言っているわけではありません:)

于 2009-10-28T07:19:12.140 に答える
0

Java AbstractQueuedSynchronizer(およびその兄弟AbstractQueuedLongSynchronizer) も同様に機能するか、少なくとも同様に実装できます。これらの型は、 や など、Java ライブラリのいくつかの同時実行プリミティブの基礎を形成しReentrantLockますFutureTask

これは、原子整数を使用して状態を表すことによって機能します。ロックでは、値 0 をアンロック、1 をロックと定義できます。ロックを取得しようとするスレッドは、アトミックな比較および設定操作によってロック状態を 0 から 1 に変更しようとします。試行が失敗した場合、現在の状態は 0 ではありません。これは、ロックが他のスレッドによって所有されていることを意味します。

AbstractQueuedSynchronizerまた、 CLH キューを維持することで、ロックの待機と条件の通知を容易にします。CLH キューは、ロックの取得または条件による通知の受信を待機しているスレッドの行を表す、ロックのないリンクされたリストです。このような通知により、条件で待機しているスレッドの 1 つまたはすべてが、関連するロックの取得を待機しているスレッドのキューの先頭に移動します。

この機構のほとんどは、状態を表すアトミック整数と、待機中のキューごとのいくつかのアトミック ポインターの観点から実装できます。どのスレッドが競合して状態変数を (たとえば を介してAbstractQueuedSynchronizer#tryAcquire(int)) 検査および変更するかの実際のスケジューリングは、そのようなライブラリの範囲外であり、ホスト システムのスケジューラに委ねられます。

于 2009-12-07T01:09:52.600 に答える