我有一个代码如下的课程
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
)is guaranteed to be atomic时,这应该可以在单个CPU上正常工作。
我可以(也在理论上)制作m_client
变量volatile
,然后通过防止其他CPU的无序读取在多个cpu中安全,但问题是,锁定时写入是否可以安全地读取而不会发生变化?
在写入“刷新”CPU缓存时是否锁定,以便在读取时不会出现乱序?
答案 0 :(得分:3)
lock
(通常,它在.NET中扩展到的Monitor
)是一个内存屏障 - 特别是读取时的屏障,发布时的写屏障。对于volatile
,它为每次读取和写入字段添加了障碍。所以,是的,您应该对volatile
保持安全(假设您未显示的其余代码正在正确执行所有操作)。
答案 1 :(得分:0)
如果你没有m_context,你就不需要锁,因为read和write都是原子的。但是,如果读取m_client时也使用m_context,则必须同时锁定两者以防止在更新m_client之后但在更新m_context之前存在上下文切换的情况。
答案 2 :(得分:0)
如果我记得,性能不是很好,但您可以使用ReaderWriterLock来实现1位作家和多位读者。