【问题标题】:Ensuring writes are seen from different reading threads确保从不同的读取线程看到写入
【发布时间】:2019-03-18 10:39:12
【问题描述】:

给定以下类:

class C
{
   public int x = 0;

   public void F() {
       new Thread(G).Start();
       while (x == 0) { Thread.Sleep(TimeSpan.FromMilliseconds(1)); }
   }

   public void G() {
      Thread.Sleep(TimeSpan.FromMilliseconds(1000));
      Interlocked.Exchange(ref x, 1);
   }
}

我假设在C# 标准下允许new C().F() 永远运行是的,因为没有什么可以强制F() 在每次访问时从主内存中检索x 的值。这里的Interlocked.Exchange 甚至没有帮助,因为F() 没有看到G() 的实现,因此可能会优化主内存的访问。

这个分析正确吗?

此外,我知道让x volatile 可以解决这个问题,但是还有什么可以解决这个问题的吗?

【问题讨论】:

  • 不要在 C# 中使用 volatile,除非你真的,真的知道你的方法:stackoverflow.com/a/19384758/1086121。一个普通的lock 声明是解决这个问题的方法。
  • 正如 canton7 提到的,锁定对象将迫使其他线程等待(因此同步)锁定线程释放它,从而使其成为原子。
  • 写入被其他线程看到。假设有 其他线程可以查看写入 - new Thread(G).Start(); 创建一个孤立的线程对象,该对象将被垃圾收集
  • 即使解决了,阅读也需要同步,通过锁或Interlocked.CompareExchange
  • 您也可以使用Thread.VolatileWriteThread.VolatileRead(作为volatile 关键字的替代品)。 Interlocked.Exchange 这里根本不需要,因为 int32 分配是原子的。

标签: c# multithreading thread-synchronization


【解决方案1】:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-29
    • 2014-07-15
    • 1970-01-01
    相关资源
    最近更新 更多