如果我在写入变量时锁定,在读取时是否还需要锁定,如果读取是原子的?

Ori*_*rds 5 c# multithreading locking volatile

我有一个代码如下的类

private readonly object m_lock = new object();

private IClient m_client
private object m_context;
Run Code Online (Sandbox Code Playgroud)

设置客户端和上下文时,我按如下方式锁定

lock(m_lock)
{
    m_client = theClientFromSomewhere;
    m_context = contextObject;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是,如果我只需要m_client自己解决,这样做是否安全?

var localClient = m_client;

Debug.Assert(localClient != null);
localClient.DoStuff();
Run Code Online (Sandbox Code Playgroud)

m_client读取(在分配时localClient)保证是原子的,因此这应该在单个CPU上正常工作.

我可以(也在理论上)制作m_client变量volatile,然后通过防止其他CPU的无序读取,这在多个cpu中是安全的,但问题是,写入时锁定是否可以安全地读取不稳定?

写入"刷新"CPU缓存时是否锁定,以便在读取时不会出现乱序?

Pav*_*aev 3

lock在 C# 中(以及通常Monitor在 .NET 中扩展为的内存屏障)是内存屏障 - 具体来说,是获取时的读屏障、释放时的写屏障。至于,它为该字段的每次读写volatile添加了一个屏障。所以,是的,您应该放心(假设您没有显示的其余代码正在正确执行所有操作)。volatile