0%

什么是锁、互斥量、原子操作解决不了的并发问题

2020年3月17日 下午5:24

并发代码1

1
2
x = 0;
y = 0;

并发代码2:

1
2
x = 1;
y = 2;

并发代码3

1
2
3
4
if (y == 2) {
x = 3;
y = 4;
}

总结:

当 1 + 3 并发时—>可以解决的问题,结果是确定的

我们可以用原子操作的内存顺序来解决:

1
2
3
x = 1;
// 在 x = 1 和 y = 2 两句语句之间加入内存屏障,禁止这两句语句交换顺序
y.store(2, memory_order_release);
1
2
3
4
5
if (y.load(memory_order_acquire) == 2) {
x = 3;
//在线程 2 我们对 y 的读取应当使用获得语义,但存储只需要松散内存序即可
y.store(4, memory_order_relaxed);
}

我们可以用下图示意一下,每一边的代码都不允许重排越过黄色区域,且如果 y 上的释放早于 y 上的获取的话,释放前对内存的修改都在另一个线程的获取操作后可见

当1 + 2并发时—>不论采用哪种方式解决,结果都是不确定的

  • 你只能保证并发代码1, 并发代码2各自是禁止交换顺序
  • 你无法避免保证1 + 2并发,线程的交叉执行,所以,结果一定是不确定的!