6

c#lockキーワードは、競合を処理するために「yielding」、「spin-locking」、またはハイブリッドアプローチを使用しますか?

これまでのところ、.netlockステートメントを検索しても答えは見つかりませんでした。これ以上見つけたら投稿します。これまでのところ、私が見つけたのは、いつスピンロックを使用すべきかということです... Meckiによる適切な言葉で受け入れられた答えがあります。

しかし、誰かが持っている場合、私は.net / c#に関するいくつかの決定的な答えまたはドキュメントを探しています。

4

3 に答える 3

10

次のコード:

lock (_syncRoot)
{
    // Do stuff
}

コンパイラによって次のように変換されます。

Monitor.Enter(_syncRoot)
try
{
    // Do stuff
}
finally
{
    Monitor.Exit(_syncRoot);
}

これはナイーブな(そして古い)実装であり、実際には.NET 4.0では実装は多かれ少なかれこれです(完全なリファレンスについてはEricのブログを参照してください)。

bool locked = false;
try
{
    Monitor.Enter(_syncRoot, ref locked);
}
finally
{
    if (locked)
        Monitor.Exit(_syncRoot);
}

編集済み

それは問題がどのようにMonitor.Enter()機能するかということです。ええと、デフォルトのMono実装はセマフォを使用してロックを取得しますが、Microsoft.NET実装は動作が異なります。

段落が私の注意を引いたときに(Joe Duffyによる)並行Windowsプログラミングを読んでいたとき、私の最初の答えは「いいえ、一般的な場合にはパフォーマンスが良くない可能性があるため、回転を使用しません」と述べました。正解は「はい、.NETMonitorはスピニングを使用します」です。.NETMonitorとWindowsの両方のクリティカルセクションは、カーネルオブジェクトの真の待機にフォールバックする前に、短いスピンを実行します。このアルゴリズムは「2フェーズロックプロトコル」と呼ばれ、コンテキストスイッチとカーネル遷移が非常に拡張的であるため適切です。マルチプロセッサマシンでは、回転によって両方を回避できます。

さらに、これらは実装の詳細であり、リリースごとに変更される可能性があることを忘れないでください(または、JITコンパイラーのためにアルゴリズムがハードウェアごとに異なる可能性があります)。

于 2012-07-06T12:12:43.847 に答える
1
lock (obj)
{
}

Monitorの単なる構文糖衣でした。試してみてください...最後に。

Monitor.Enter(obj);
try
{
}
finally
{
    Monitor.Exit(obj);
}

今では少し良くなっています(私を最新の状態に保ってくれたMarkとAdrianoに感謝します)。

bool locked = false;  
try  
{  
    Monitor.Enter(_syncRoot, ref locked);  
}  
finally  
{  
    if (locked)  
        Monitor.Exit(_syncRoot);  
} 
于 2012-07-06T12:11:37.647 に答える
0

これは、lock()がMonitor.Enter/ExitをラップするというMicrosoftのドキュメントです。

「EnterメソッドとExitメソッドをtry…finallyブロックでラップするC#ロックステートメントを使用してください。」

http://msdn.microsoft.com/en-us/library/de0542zz.aspxから

スピンロックタイプが必要な場合は、ReaderWriterLockSlim()を使用できます。

http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx

于 2012-07-06T12:15:23.480 に答える