假设两个线程 A 、B,共享变量 V,A 和 B 分别跑在 CPU1 、CPU2 上,各自 cache 中有 V 所在 cache line 的副本,其中的 V 分别为 V1 、V2 。
那么当 A 直接修改 V,而没有使用锁、CAS 等同步原语,那么 CPU1 只是单纯修改自己的 V1 而没有写回内存,会不会导致 CPU2 的 V2 失效?即一个 CPU 的某块缓存失效的时机是内存发生了修改,还是其他 CPU 的相同缓存发生了修改?
我的理解是因为 cache 的修改写入内存是 write back,而不是立即写入内存,所以没有使用同步原语的情况下,线程 A 对 V1 的修改,应该对内存和线程 B 都是不可见的,直到未来某一时刻 A 的 cache 刷回内存,B 所在的 CPU2 中的 cache line 才会被标记为失效,之后才能读到 A 对 V 的修改。
因此为了保证多个线程对共享变量并发操作的可见性,访问共享变量需要同步原语,保证每次写都写到内存上,每次读都读到是内存上最新的值。
这是我从 The Go Memory Model 和 TGPL 书上的理解,不知道理解得对不对,顺便问下大家有没有系统讲解多核缓存的书籍或资料?
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.