当没有锁定和除父线程外没有并发数据访问时,内存屏障是否确保跨线程的数据一致性?
下面是我的场景:
我希望确保:
下面是我编写代码的计划:
public class State
{
public string Data1 { get; set; }
public string Data2 { get; set; }
public int[] SomeArray { get; set; }
}
static void Main(string[] args)
{
var state = new State();
state.Data1 = "Initial Data1 From MainThread";
state.Data2 = "Initial Data2 From MainThread";
state.SomeArray = new []{ 0, -1, -2 };
Thread.MemoryBarrier();//TMB 0.1 Force storing all written value in order to be visible for the child threads
var thread1 = new Thread(o =>
{
//Assert.AreEqual("Initial Data1 From MainThread", input.Data1);
Thread.MemoryBarrier();//TMB 1.1 Force read value pushed from mainThread
var input = (State)o;
Assert.AreEqual("Initial Data1 From MainThread", input.Data1);
input.Data1 = "Modified by Thread 1";
input.SomeArray[1] = 11;
Thread.MemoryBarrier();//TMB 1.2 Force storing all written value in order to be visible for the Main threads
});
var thread2 = new Thread(o =>
{
//Assert.AreEqual("Initial Data2 From MainThread", input.Data2);
Thread.MemoryBarrier();//1.1 Force read value pushed from mainThread
var input = (State)o;
Assert.AreEqual("Initial Data2 From MainThread", input.Data2);
input.Data2 = "Modified by Thread 2";
input.SomeArray[2] = 22;
Thread.MemoryBarrier();//TMB 1.2 Force storing all written value in order to be visible for the Main threads
});
thread1.Start(state);
thread2.Start(state);
thread1.Join();
thread2.Join();
//Assert.AreEqual("Modified by Thread 1", state.Data1);
//Assert.AreEqual("Modified by Thread 2", state.Data2);
Thread.MemoryBarrier();//TMB 0.1 Force retrieving all written value from the child threads
Assert.AreEqual("Modified by Thread 1", state.Data1);
Assert.AreEqual("Modified by Thread 2", state.Data2);
Assert.AreEqual(0, state.SomeArray[0]);
Assert.AreEqual(11, state.SomeArray[1]);
Assert.AreEqual(22, state.SomeArray[2]);
Console.WriteLine("Done");
Console.ReadLine();
}
这些问题是:
来自are数组线程安全:
我相信,如果每个线程只在数组的单独部分上工作,一切都会很好。 如果您要共享数据(例如,在线程之间通信),那么您将需要某种内存障碍来避免内存模型问题。
。。。
乔恩·斯基特
由此,我相信答案是:
通常,我会提倡一种稍微偏执的方法,代码可能会更改,并发问题可能很难检测到。 一些经验法则: