7

この記事:http ://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf (12ページ)は、ロックとメモリバリアの違いを生むようです

ロック、メモリバリア、セマフォの違いを知りたいのですが。

(他の質問ではロックと同期オブジェクトの違いについて言及しているかもしれませんが、ロックとメモリバリアの違いについては何も見つかりませんでした)

4

3 に答える 3

12
  • メモリバリアは、メモリアクセスを注文する方法です。コンパイラとCPUは、最適化するためにこの順序を変更できますが、マルチスレッド環境では、これが問題になる可能性があります。他との主な違いは、スレッドがこれによって停止されないことです。
  • ロックまたはミューテックスにより、コードにアクセスできるのは1つのスレッドのみになります。このセクションでは、環境をシングルスレッドとして表示できるため、メモリバリアは必要ありません。
  • セマフォは基本的に、増加(v())または減少(p())できるカウンターです。カウンターが0の場合、p()は、カウンターが0でなくなるまでスレッドを停止します。これはスレッドを同期する方法ですが、ミューテックスまたは条件変数を使用することをお勧めします(物議を醸していますが、それは私の意見です)。初期カウンターが1の場合、セマフォはバイナリセマフォと呼ばれ、ロックに似ています。

ロックとセマフォの大きな違いは、スレッドがロックを所有しているため、他のスレッドがロックを解除しようとしないことですが、セマフォの場合はそうではありません。

于 2012-05-11T13:41:03.950 に答える
10

メモリバリア(フェンスとも呼ばれます)はハードウェア操作であり、グローバルに表示されるストアへのさまざまな読み取りと書き込みの順序を保証します。典型的な最新のプロセッサでは、メモリアクセスはパイプライン化されており、順序が狂っている可能性があります。メモリバリアは、これが起こらないことを保証します。フルメモリバリアは、それに先行するすべてのロードとストアが、それに続くロードまたはストアの前に発生することを保証します。(多くのプロセッサは部分的なバリアをサポートしています。たとえば、Sparcでは、 membar #StoreStoreそれ以前に発生したすべてのストアが、その後に発生するストアの前に他のすべてのプロセスに表示されるようになります。)

これがメモリバリアのすべてです。スレッドなどをブロックしません。

ミューテックスとセマフォは、オペレーティングシステムに実装されている、より高いレベルのプリミティブです。ミューテックスロックを要求するスレッドは、そのミューテックスが解放されるまでブロックし、OSによって実行が一時停止されます。OSのカーネルコードには、ミューテックスを実装するためのメモリバリア命令が含まれていますが、それだけではありません。メモリバリア命令は、必要な条件(最大でマイクロ秒程度)が満たされるまでハードウェアの実行(すべてのスレッド)を一時停止し、この間、プロセッサ全体が停止します。ミューテックスをロックしようとして、別のスレッドがすでにそれを持っている場合、ミューテックスを保持している人がミューテックスを解放するまで、OSはスレッドを一時停止します(そしてあなたのスレッドのみ-プロセッサは他のスレッドを実行し続けます)。でも数日。(もちろん、数百ミリ秒を超える場合は、

最後に、セマフォとミューテックスの間に実際には大きな違いはありません。ミューテックスは、カウントが1のセマフォと見なすことができます。

于 2012-05-11T14:05:57.647 に答える
2

今のところ簡単な説明。

ロック

このコードが続行できるかどうかのアトミックテストです

lock (myObject)
{
    // Stuff to do when I acquire the lock
}

これは通常、変数を単一のアトミック操作としてテストおよび設定する単一のCPU命令です。詳細はこちら、http://en.wikipedia.org/wiki/Test-and-set#Hardware_implementation_of_test-and-set_2

メモリバリア

これらの命令を順不同で実行できないことをプロセッサに示すヒントです。これがないと、ダブルチェックロックの場合のように、命令が順不同で実行される可能性があり、ロックが実行される前に2つのヌルチェックが実行される可能性があります。

Thread.MemoryBarrier();
public static Singleton Instance()
{
    if (_singletonInstance == null)
    {
        lock(myObject)
        {
            if (_singletonInstance == null)
            {
                _singletonInstance = new Singleton();
            }
        }
    }
}

これは、メモリバリアを実装する一連のCPU命令でもあり、CPUに順不同で実行できないことを明示的に通知します。

セマフォ

通常は複数のスレッド用であることを除いて、ロックに似ています。つまり、たとえば10回の同時ディスク読み取りを処理できる場合は、セマフォを使用します。プロセッサに応じて、これはそれ自体の命令、または負荷を伴うテストアンドセット命令のいずれかであり、割り込みを回避します(たとえば、ARMの場合)。

于 2012-05-11T13:29:16.327 に答える