C# 不理解C语言中记忆障碍的用途#
在我开始之前,我只想承认,我知道之前有一些关于这方面的问题,我已经链接到下面: 也就是说。。。这两本书我都读过了,但我还是不太明白到底发生了什么C# 不理解C语言中记忆障碍的用途#,c#,thread-safety,C#,Thread Safety,在我开始之前,我只想承认,我知道之前有一些关于这方面的问题,我已经链接到下面: 也就是说。。。这两本书我都读过了,但我还是不太明白到底发生了什么 class Foo { int _answer; bool _complete; void A() { _answer = 123; Thread.MemoryBarrier(); // Barrier 1 _complete = true; Thread.MemoryBarrier();
class Foo
{
int _answer;
bool _complete;
void A()
{
_answer = 123;
Thread.MemoryBarrier(); // Barrier 1
_complete = true;
Thread.MemoryBarrier(); // Barrier 2
}
void B()
{
Thread.MemoryBarrier(); // Barrier 3
if (_complete)
{
Thread.MemoryBarrier(); // Barrier 4
Console.WriteLine (_answer);
}
}
}
简而言之,这段代码片段取自C#4.0。目前,我了解到没有内存障碍的问题是,B可能会在a之前运行,B不会打印任何内容,因为\u complete
可能会被评估为false
每个功能中的“屏障”彼此完全分离,并且不像屏障是有序的Thread.MemoryBarrier(1)
或任何编译器不知道的A应该在B之前
有人能帮我澄清一下吗?谢谢
编辑:我想我对指令排序的工作原理感到困惑。。。但我对这个话题感到困惑,甚至不知道如何恰当地表达我的问题
目前,我理解没有记忆障碍的问题是
有可能在a和B打印之前B将运行
因为_complete,所以不能将任何内容计算为false
不,问题在于编译器、抖动或CPU指令重新排序。
这可能是一种情况,当他们中的一些人可以重新排序
_answer = 123;
_complete = true;
对于一些优化的说明,从单线程应用程序的角度来看,它们的顺序并不重要
现在假设它们被重新排序为
_complete = true;
_answer = 123;
现在:
- 线程1集合
\u complete=true
- 线程2获取
\u完成
- 评估
条件if
- 获取_答案(即0)
- Console.WriteLine(_answer)->0
- 评估
- 线程1集合
\u答案=123
代码逻辑中断。OMG!我现在完全明白了,真不敢相信事情会这么简单。我想得太多了。如果您不介意的话,我还有一个后续问题。代码的哪一部分是Thread.MemoryBarrier();控制?例如第一个调用线程.MemoryBarrier()。。。“阻止”被重组的是哪段代码?第一个内存障碍设置了完整的围栏,并禁止移动
\u answer=123代码>旁边的\u complete=true代码>和反之亦然,第二道屏障将释放CPU的现金线,并确保\u应答
和\u完成
是新的。