Thread.MemoryBarrier()如何刷新缓存?

问题描述 投票:0回答:1

Thread.MemoryBarrier()
使程序从主存中获取值而不是使用寄存器,但是如果我们有以下程序:

_a = xxx;
_b = xxx;
Thread.MemoryBarrier();
_c = xxx;
_d = xxx;

是否所有 _a、_b、_c、_d 值都从主内存中获取,还是仅从主内存中获取包装变量 _b 和 _c,还是仅从主内存中获取屏障之后的 _c 和

_d

c# .net multithreading clr thread-synchronization
1个回答
2
投票

根据

Thread.MemoryBarrier
方法的文档:

按如下方式同步内存访问:执行当前线程的处理器无法以这样的方式重新排序指令:调用

MemoryBarrier()
之前的内存访问在调用
MemoryBarrier()
之后的内存访问之后执行。

这是 Microsoft 提供的唯一保证。其他一切,比如从主内存而不是寄存器中获取值,都只是语言学。如果您想以 Microsoft 认为正确的方式编写程序,那么您应该将

Thread.MemoryBarrier
用于其预期目的。在这个具体的例子中:

_a = xxx;
_b = xxx;
Thread.MemoryBarrier();
_c = xxx;
_d = xxx;

...我们唯一可以 100% 肯定地说的是,作业

_c = xxx; _d = xxx;
不能在作业
_a = xxx; _b = xxx;
之前发生。中间
Thread.MemoryBarrier();
确保 C# 编译器和 .NET Jitter 都不会发出以错误顺序分配值的机器代码。

您可以在 Miguel Angelo 的

这个答案
中找到 Thread.MemoryBarrier() 方法的一个很好的使用示例。它的用途是确保在它所保存的对象完全初始化之前,不会分配
static
字段。

¹ 当然假设 C# 编译器和 .NET Jitter 没有错误。在这种情况下,微软将很难尽快修复它。

© www.soinside.com 2019 - 2024. All rights reserved.