问题
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?
回答1:
No, synchronization mechanisms generate implicit memory fences. All data modified by a thread will be visible after the thread is joined.
回答2:
From the documentation it looks like they are not required -
MemoryBarrier is required only on multiprocessor systems with weak memory ordering (for example, a system employing multiple Intel Itanium processors).
For most purposes, the C# lock statement, the Visual Basic SyncLock statement, or the Monitor class provide easier ways to synchronize data.
As you are blocking with join it is even more not necessary.
回答3:
You don't need the first memory barrier. You only need to call them before accessing data that has been modified in a separate thread. Since you aren't doing so inside 'thread', you don't need the call.
You can get rid of the second one if you plan on keeping the Join call. If you keep the second call, you can get rid of Join.
来源:https://stackoverflow.com/questions/12444891/are-memory-barriers-required-when-joining-on-a-thread