EventWaitHandle是否有任何隐式的MemoryBarrier?

tca*_*vin 10 .net c# vb.net multithreading volatile

这个网站的新用户,如果我没有以可接受的方式发帖,请告诉我.

我经常在下面的示例中编写一些代码(为了清楚起见,使用Dispose ommtited等内容).我的问题是,如图所示需要挥发物吗?或者,当我读过Thread.Start时,ManualResetEvent.Set是否有隐式内存屏障?或者显式的MemoryBarrier调用是否比挥发性更强?还是完全错了?此外,据我所见,某些操作中的"隐式记忆障碍行为"没有记录,这是非常恐怖的,这些操作的列表是否存在?

谢谢,汤姆

:

class OneUseBackgroundOp
{

   // background args
   private string _x;
   private object _y;
   private long _z;

   // background results
   private volatile DateTime _a
   private volatile double _b;
   private volatile object _c;

   // thread control
   private Thread _task;
   private ManualResetEvent _completedSignal;
   private volatile bool _completed;

   public bool DoSomething(string x, object y, long z, int initialWaitMs)
   {
      bool doneWithinWait;

      _x = x;
      _y = y;
      _z = z;

      _completedSignal = new ManualResetEvent(false);

      _task = new Thread(new ThreadStart(Task));
      _task.IsBackground = true;
      _task.Start()

      doneWithinWait = _completedSignal.WaitOne(initialWaitMs);

      return doneWithinWait;

   }

   public bool Completed
   {
      get
      {
         return _completed;
      }
   }

   /* public getters for the result fields go here, with an exception
      thrown if _completed is not true; */

   private void Task()
   {
      // args x, y, and z are written once, before the Thread.Start
      //    implicit memory barrier so they may be accessed freely.

      // possibly long-running work goes here

      // with the work completed, assign the result fields _a, _b, _c here

      _completed = true;
      _completedSignal.Set();

   }

}
Run Code Online (Sandbox Code Playgroud)

wek*_*mpf 3

请注意,这是即兴的,没有仔细研究您的代码。我不认为Set 执行内存屏障,但我不明白这与您的代码有何相关?似乎更重要的是 Wait 是否执行一个操作,它确实执行了。因此,除非我在花 10 秒查看您的代码时错过了某些内容,否则我不认为您需要 挥发物。

编辑:评论过于严格。我现在指的是马特的编辑。

马特的评估做得很好,但他遗漏了一个细节。首先,让我们提供一些乱七八糟的东西的定义,但这里没有澄清。

易失性读取读取一个值,然后使 CPU 缓存无效。易失性写入会刷新缓存,然后写入值。内存屏障会刷新缓存,然后使其无效。

.NET 内存模型确保所有写入都是易失性的。默认情况下,不会进行读取,除非进行了显式 VolatileRead,或者在字段上指定了 volatile 关键字。此外,互锁方法强制缓存一致性,并且所有同步概念(Monitor、ReaderWriterLock、Mutex、Semaphore、AutoResetEvent、ManualResetEvent 等)在内部调用互锁方法,从而确保缓存一致性。

同样,所有这些都来自 Jeffrey Richter 的书“CLR via C#”。

我一开始就说过,我不认为赛特执行了记忆屏障。然而,进一步思考 Richter 先生所说的,Set 将执行互锁操作,因此也将确保缓存一致性。

我坚持我最初的主张,即这里不需要 volatile。

编辑2:看起来你正在构建一个“未来”。我建议您研究一下PFX,而不是自己动手。