我是这个网站的新手,所以如果我没有以可接受的方式发帖,请告诉我。
我经常按照下面的示例编写一些代码(为了清楚起见,省略了诸如 Dispose 之类的内容。)。我的问题是,是否需要如图所示的挥发物?或者 ManualResetEvent.Set 是否像我读过的 Thread.Start 那样具有隐式内存屏障?或者显式的 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();
}
}
请注意,这是即兴的,没有仔细研究您的代码。我不thinkSet 执行内存屏障,但我不明白这与您的代码有何相关?似乎更重要的是 Wait 是否执行一个操作,它确实执行了。因此,除非我在花 10 秒查看您的代码时错过了某些内容,否则我不认为您需要 挥发物。
编辑:评论过于严格。我现在指的是马特的编辑。
马特的评估做得很好,但他遗漏了一个细节。首先,让我们提供一些乱七八糟的东西的定义,但这里没有澄清。
易失性读取读取一个值,然后使 CPU 缓存无效。易失性写入会刷新缓存,然后写入值。内存屏障会刷新缓存,然后使其无效。
.NET 内存模型确保所有写入都是易失性的。默认情况下,不会进行读取,除非进行了显式 VolatileRead,或者在字段上指定了 volatile 关键字。此外,互锁方法强制缓存一致性,并且所有同步概念(Monitor、ReaderWriterLock、Mutex、Semaphore、AutoResetEvent、ManualResetEvent 等)在内部调用互锁方法,从而确保缓存一致性。
同样,所有这些都来自 Jeffrey Richter 的书“CLR via C#”。
我一开始就说过我没有think设置执行了内存屏障。然而,进一步思考 Richter 先生所说的,Set 将执行互锁操作,因此也将确保缓存一致性。
我坚持我最初的主张,即这里不需要 volatile。
编辑2:看起来你正在构建一个“未来”。我建议你看看,而不是自己滚动。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)