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

标签 c# multithreading locking volatile

我有一个类,代码如下

private readonly object m_lock = new object();

private IClient m_client
private object m_context;

在设置client和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 时)is guaranteed to be atomic ,所以这应该可以在单个 CPU 上正常工作。

我可以(在理论上)使 m_client 变量成为 volatile,然后通过防止其他 CPU 的乱序读取,这在多个 cpu 上是安全的,但问题是,写入时锁定是否可以在不发生 volatile 的情况下安全读取?

写入时锁定是否会“刷新”CPU 缓存,以便在读取时不会发生乱序?

最佳答案

C# 中的

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

关于c# - 如果我在写入变量时锁定,如果读取是原子的,我是否也需要在读取时锁定?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1169562/

相关文章:

c# - 无需 oAuth 的 Instagram 登录

c# - CLR 如何优化属性引用?

java - Spring Autowiring 线程类

c++ - ThreadSanitizer 说我的 spin_lock 有数据竞争,但是怎么办?

c++ - 使用原子实现票证锁会产生额外的 mov

c# - 比较 IP 地址(存储为 varbinary)

c# - 在 ASP.NET RadioButtonList 中向 LI 添加类

java - Log4j 挂起我的应用程序我做错了什么?

c++ - 你需要只读锁定吗

multithreading - 锁(线程)是原子的吗?