## 9.2\. Happens Before
在一个单独的goroutine中,变量的读和写操作顺序和代码所写的顺序一致。因此,在变量值没有 被改变的时候, 编译器和处理器可能会记录变量的操作顺序。但是,这种先验性的顺序记录会导致 在两个不同的goroutine对变量操作 顺序记录有差别。例如,一个goroutine执行 a = 1; b = 2; , 但是在另一个goroutine中可能会现感知到b被更新。
为了解决这种二义性问题,Go语言中引进一个happens before的概念,它用于描述 对内存操作的先后顺序问题。如果 事件 e1 happens before 事件 e2,我们说 事件 e2 happens after e1。 如果, `事件e1 does not happen before 事件 e2,并且 does not happen after e2,我们说 事件e1和 e2同时发生`。
对于一个单一的goroutine,happens before 的顺序和代码的顺序是一致的。
如果能满足以下的条件,一个对变量v的读事件r可以 感知到另一个对变量v的写事件w:
1. 写事件w happens before 读事件r。
2. 没有既满足 happens after w 同时满主 happens before r的对变量v的写事件w。
为了保证读事件r可以感知对变量v的写事件,我们首先要 确保w是变量v的唯一的写事件。同时还要满足以下条件:
1. 写事件w happens before 读事件r。
2. 其他对变量v的访问必须 happens before 写事件w 或者 happens after 读事件r。
第二组条件比第一组条件更加严格。因为,它要求在w和 r并行执行的程序中不能再有其他的读操作。
对于在单一的goroutine中两组条件是等价的,读事件可以确保感知到对变量的写事件。但是,对于在 两个goroutines共享变量v,我们必须通过同步事件来保证 happens-before 条件 (这是读事件感知写事件的必要条件)。
将变量v自动初始化为零也是属于这个内存操作模型。
读写超过一个机器字长度的数据,顺序也是不能保证的。
- 1. 关于本文
- 2. Go语言简介
- 3. 安装go环境
- 3.1. 简介
- 3.2. 安装C语言工具
- 3.3. 安装Mercurial
- 3.4. 获取代码
- 3.5. 安装Go
- 3.6. 编写程序
- 3.7. 进一步学习
- 3.8. 更新go到新版本
- 3.9. 社区资源
- 3.10. 环境变量
- 4. Go语言入门
- 4.1. 简介
- 4.2. Hello,世界
- 4.3. 分号(Semicolons)
- 4.4. 编译
- 4.5. Echo
- 4.6. 类型简介
- 4.7. 申请内存
- 4.8. 常量
- 4.9. I/O包
- 4.10. Rotting cats
- 4.11. Sorting
- 4.12. 打印输出
- 4.13. 生成素数
- 4.14. Multiplexing
- 5. Effective Go
- 5.1. 简介
- 5.2. 格式化
- 5.3. 注释
- 5.4. 命名
- 5.5. 分号
- 5.6. 控制流
- 5.7. 函数
- 5.8. 数据
- 5.9. 初始化
- 5.10. 方法
- 5.11. 接口和其他类型
- 5.12. 内置
- 5.13. 并发
- 5.14. 错误处理
- 5.15. Web服务器
- 6. 如何编写Go程序
- 6.1. 简介
- 6.2. 社区资源
- 6.3. 新建一个包
- 6.4. 测试
- 6.5. 一个带测试的演示包
- 7. Codelab: 编写Web程序
- 7.1. 简介
- 7.2. 开始
- 7.3. 数据结构
- 7.4. 使用http包
- 7.5. 基于http提供wiki页面
- 7.6. 编辑页面
- 7.7. template包
- 7.8. 处理不存在的页面
- 7.9. 储存页面
- 7.10. 错误处理
- 7.11. 模板缓存
- 7.12. 验证
- 7.13. 函数文本和闭包
- 7.14. 试试!
- 7.15. 其他任务
- 8. 针对C++程序员指南
- 8.1. 概念差异
- 8.2. 语法
- 8.3. 常量
- 8.4. Slices(切片)
- 8.5. 构造值对象
- 8.6. Interfaces(接口)
- 8.7. Goroutines
- 8.8. Channels(管道)
- 9. 内存模型
- 9.1. 简介
- 9.2. Happens Before
- 9.3. 同步(Synchronization)
- 9.4. 错误的同步方式
- 10. 附录
- 10.1. 命令行工具
- 10.2. 视频和讲座
- 10.3. Release History
- 10.4. Go Roadmap
- 10.5. 相关资源