如果一个线程A产生另一个线程B,其唯一目的是写入一个变量V然后等待它终止,那么是否需要内存屏障以确保后续读取线程A上的V是新的?我不确定终止/加入操作中是否有任何隐含的障碍使它们变得多余。
以下是一个例子:
public static T ExecuteWithCustomStackSize<T>
(Func<T> func, int stackSize)
{
T result = default(T);
var thread = new Thread(
() =>
{
result = func();
Thread.MemoryBarrier(); // Required?
}
, stackSize);
thread.Start();
thread.Join();
Thread.MemoryBarrier(); // Required?
return result;
}
是否需要上述代码段中的两个(或更多)障碍?
答案 0 :(得分:3)
不,同步机制会生成隐式内存防护。在线程加入后,线程修改的所有数据都将可见。
答案 1 :(得分:0)
从文档中看起来它们不是必需的 -
仅在内存排序较弱的多处理器系统上需要MemoryBarrier(例如,采用多个Intel Itanium处理器的系统)。
对于大多数用途,C#lock语句,Visual Basic SyncLock语句或Monitor类提供了更简单的数据同步方法。
当你阻止加入时,更没有必要。
答案 2 :(得分:0)
您不需要第一个内存屏障。 您只需在访问已在单独线程中修改的数据之前调用它们。 由于你没有在'thread'中这样做,所以你不需要这个电话。
如果你计划保持加入电话,你可以摆脱第二个。 如果你保持第二次通话,你就可以摆脱加入。