11.内存可见行问题

// ----------------------|----------------------|
//       线程 A           |     线程 B           |
//                       |                      |
//      |---------|      |     |---------|      |
//      |  控制器  |      |     |  控制器  |      |
//      |---------|      |     |---------|      |
//      |  运算器  |      |     |   运算器 |      |
//      |---------|      |     |---------|      |
//      | L1 Cache|      |     | L1 Cache|      |
//      |---------|      |     |---------|      |
// ---------------------------------------------|
//                  L2  Cache                   |
// ---------------------------------------------|
//                     主内存                    |
//      |---------|           |---------|       |
//      | 共享变量1|           | 共享变量2 |      |
//      |---------|           |---------|       |
// ---------------------------------------------|

假如线程 A 和线程 B 同时处理一个共享变量,使用图所示 CPU 架构,
假设线程 A 和线程 B 使用不同 CPU 执行,并且当前两级 Cache 都为空, 那么这时候由于 Cache 的存在,将会导致内存不可见问题, 具体看下面的分析。

  • 线程 A 首先获取共享变量 X 的值,由于两级 Cache 都没有命中 ,所以加载主内存中 X 的值,假如为 0。
    然后把 X=O 的值缓存到两级缓存, 线程 A 修改 X 的值为 1, 然后将其写入两级 Cache, 并且刷新到主内存。
    线程 A 操作完毕后,线程 A 所在的 CPU 的两级 Cache 内和主内存里面的 X 的值都是 1。
  • 线程 B 获取 X 的值,首先一级缓存没有命中,然后看二级缓存,二级缓存命中了 , 所以返回 X= 1 。
    到这里一切都是正常的, 因为这时候主 内存中也是 X=1 。然后线 程 B 修改 X 的值为 2,
    并将其存放到线程 2 所在的一级 Cache 和共享二级 Cache 中,最后更新主内存中 X 的值为 2,到这里一切都是好的。
  • 线程 A 这次又需要修改 X 的值, 获取时一级缓存命中, 并且 X=1,到这里问题就出现了,明明线程 B 已经把 X 的值修改为了 2,
    为何线程 A 获取的还是 1 呢?这就是共享变量的内存不可见问题, 也就是线程 B 写入的值对线程 A 不可见
posted @ 2019-08-17 10:26  fly_bk  阅读(137)  评论(0编辑  收藏  举报