5

次のようなコードのクラスがあります

private readonly object m_lock = new object();

private IClient m_client
private object m_context;

クライアントとコンテキストを設定するとき、私は次のようにロックします

lock(m_lock)
{
    m_client = theClientFromSomewhere;
    m_context = contextObject;
}

私の質問は、私m_clientがそれ自体を取得する必要があるだけの場合、これを行うのは安全ですか?

var localClient = m_client;

Debug.Assert(localClient != null);
localClient.DoStuff();

m_clientは参照型であるため、読み取り(に割り当てる場合localClientはアトミックであることが保証されているため、これは単一のCPUで正常に機能するはずです。

私は(理論的にも)m_client変数volatileを作成できます。これは、他のCPUによる順不同の読み取りを防ぐことで、複数のCPU間で安全になりますが、問題は、書き込み時のロックにより、書き込みなしで安全に読み取ることができるかどうかです。揮発性ですか?

CPUキャッシュを「フラッシュ」するときにロックして、読み取りを行うときに順序が狂わないようにしますか?

4

3 に答える 3

3

lockC#(および、一般に、Monitor.NETで拡張されるもの)では、メモリバリアです。具体的には、取得時の読み取りバリア、リリース時の書き込みバリアです。については、フィールドへのすべての読み取りと書き込みにvolatileバリアを追加します。したがって、はい、安全である必要があります(表示しなかった残りのコードがすべて正しく実行されていると仮定します)。volatile

于 2009-07-23T04:12:35.757 に答える
0

m_contextがない場合は、読み取りと書き込みの両方がアトミックであるため、ロックは必要ありません。ただし、m_clientを読み取るときにm_contextも使用する場合は、m_clientの更新後、m_contextの更新前にコンテキストスイッチが発生するのを防ぐために、両方をロックする必要があります。

于 2009-07-23T04:15:34.753 に答える
0

思い出すと、パフォーマンスは良くありませんが、ReaderWriterLockを使用して 1 つのライターと複数のリーダーを実装できます。

于 2009-07-23T04:20:53.913 に答える