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保证是 atomic,所以这应该在单个 CPU 上正常工作。

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

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

4

3 回答 3

3

lock在 C# 中(通常,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 回答