5

If a thread A spawns another thread B with the single purpose of writing to a variable V and then waits for it to terminate, are memory-barriers required to ensure that subsequent reads of V on thread A are fresh? I'm unsure if there any implicit barriers in the termination / joining operations that make them redundant.

Here's an example:

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;
}

Are are either / both (or more) of the barriers in the above snippet required?

4

3 回答 3

4

不,同步机制会生成隐式内存栅栏。线程加入后,线程修改的所有数据都将可见。

于 2012-09-16T15:09:42.470 回答
0

从文档看来它们不是必需的 -

MemoryBarrier 仅在内存排序较弱的多处理器系统上需要(例如,使用多个 Intel Itanium 处理器的系统)。

对于大多数用途,C# lock 语句、Visual Basic SyncLock 语句或 Monitor 类提供了更简单的数据同步方法。

当您使用 join 阻塞时,就更没有必要了。

于 2012-09-16T06:56:51.170 回答
0

您不需要第一个内存屏障。您只需要在访问已在单独线程中修改的数据之前调用它们。由于您没有在“线程”内这样做,因此您不需要调用。

如果您打算保留加入通话,则可以摆脱第二个。如果您保留第二个电话,您可以摆脱加入。

于 2012-09-16T07:09:39.050 回答