|
|
@ -271,6 +271,10 @@ fn main() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
线程`producer`和`consumer`如果不设置`内存屏障`,那么`DATA`的值可能由于`CPU 缓存导致内存顺序的改变`
|
|
|
|
|
|
|
|
举个例子,假如`reset`中将`DATA = 0`,此时,`producer`线程中将`DATA = 100`,但由于`CPU 缓存`的原因,`DATA = 100`还没有被同步到其它`CPU 缓存`中,
|
|
|
|
|
|
|
|
此时`consumer`线程中开始读取`DATA`,结果读到了值`0`,这也就造成了`断言失败`,因此这种情况下`内存屏障`是很有必要的
|
|
|
|
|
|
|
|
|
|
|
|
原则上,`Acquire`用于读取,而`Release`用于写入。但是由于有些原子操作同时拥有读取和写入的功能,此时就需要使用`AcqRel`来设置内存顺序了。在内存屏障中被写入的数据,都可以被其它线程读取到,不会有 CPU 缓存的问题。
|
|
|
|
原则上,`Acquire`用于读取,而`Release`用于写入。但是由于有些原子操作同时拥有读取和写入的功能,此时就需要使用`AcqRel`来设置内存顺序了。在内存屏障中被写入的数据,都可以被其它线程读取到,不会有 CPU 缓存的问题。
|
|
|
|
|
|
|
|
|
|
|
|
**内存顺序的选择**
|
|
|
|
**内存顺序的选择**
|
|
|
|