c# - C#中volatile(Thread.VolatileRead/Thread.VolatileWrite)的使用

标签 c# multithreading

在多 CPU 机器上运行的多线程程序中,我是否需要使用 volatile 读/写来访问共享状态(下面示例代码中的 _data)以确保正确性。

也就是说,heap对象可以缓存在cpu上吗?

使用下面的示例并假设多线程将访问 GetValue 和 Add 方法,我需要 ThreadA 能够添加数据(使用 Add 方法)并且 ThreadB 能够立即查看/获取添加的数据(使用GetValue 方法)。那么我是否需要向 _data 添加 volatile 读/写以确保这一点?基本上我不想添加要缓存在 ThreadA 的 cpu 上的数据。

/我没有锁定(强制独占线程访问),因为代码需要超快,而且我没有从 _data 中删除任何数据,所以我不需要锁定 _data。

谢谢。

**** 更新 ****************************

很明显,你们认为使用这个示例进行无锁是个坏主意。但是我在这里会遇到什么副作用或异常?

如果一个线程正在迭代读取的值而另一个线程正在迭代更新的值,Dictionary 类型是否会抛出异常?还是我会遇到“脏读”(这对我来说没问题)?

**** 结束更新 ****************************

public sealed class Data
{
    private volatile readonly Dictionary<string, double> _data = new Dictionary<string, double>();

    public double GetVaule(string key)
    {
        double value;
        if (!_data.TryGetValue(key, out value))
        {
            throw new ArgumentException(string.Format("Key {0} does not exist.", key));
        }
        return value;
    }

    public void Add(string key, double value)
    {
        _data.Add(key, value);
    }

    public void Clear()
    {
        _data.Clear();
    }
}

感谢您的回复。关于锁,这些方法几乎经常被多个线程调用,所以我的问题是有争议的锁而不是实际的锁操作。

所以我的问题是关于 cpu 缓存,堆对象(_data 实例字段)可以缓存在 cpu 上吗?我是否需要使用 volatile 读/写来访问 _data 字段?

/此外,我坚持使用 .Net 2.0。

感谢您的帮助。

最佳答案

MSDN docs对于 Dictionary<TKey, TValue>说它对多个读者是安全的,但他们并没有像其他一些类那样提供“一个作者,多个读者”的保证。简而言之,我不会这样做。

您说您避免锁定是因为您需要代码“超快”- 您是否尝试锁定以查看开销是多少?无争议的锁非常便宜,而当锁有争议时,您就会从增加的安全性中受益。在决定担心无锁解决方案的并发问题之前,我肯定会对此进行广泛的分析。 ReaderWriterLockSlim如果您实际上有多个读者,这可能会有用,但听起来您只有一个读者和一个作者,至少目前是这样——在这种情况下,简单的锁定会更容易。

关于c# - C#中volatile(Thread.VolatileRead/Thread.VolatileWrite)的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/349192/

相关文章:

python - 在 Shell/终端或变量更改中按键时退出循环

multithreading - MFC中的工作线程终止

java - 使用compareAndSet实现线程安全

c# - Google Weather API 请求不起作用。给出请求超时

c# - 使用属性抑制 PostSharp 多播

ruby-on-rails - 如果 Puma 是多线程而不是多进程,为什么要创建多个 PID?

c++ - Windows 线程-C++

c# - 有没有办法告诉 Visual Studio 在发布的结果中包含子文件夹的配置文件?

c# - 如何从 UserPrincipal 或 PrincipalSearcher 获取域名

c# - 是否可以将 ASP.Net Core 3.1 Web 应用程序发布为单个文件