建议
对于多协程同时修改的数据,要确保序列化访问。
可以通过Channel和其他同步机制(sync和sync/atomic包)来保护数据,以保证序列化访问。
Happens-Before原则
同JMM,保证单协程程序顺序原则。
如果事件e1是happens-before事件e2,那么事件e2也happens-after事件e1。如果事件e1不是happens-before事件e2也不是happens-after事件e2,那么事件e1和事件e2被认为并发发生(concurrently)。
对变量v的读操作r能够观察到写操作w必须满足:
- 读操作r不happens-before写操作w。
- 没有其它的写操作happens-after写操作w和happens-before读操作r。
对变量v的读操作r确保观察到写操作w必须满足:
- 写操作w必须happens-before读操作r。
- 其他对变量v的写操作要么happens-before写操作w,要么happens-after读操作r。
在内存模型中,对变量v的零值初始化被认为是写操作。超过一个机器字值的读操作和写操作,表现为无指定顺序的多个机器字大小的操作。
Go Channel
发送happens-before接收
关闭happens-before因管道关闭而返回0的接收
无缓冲管道:接受happens-before发送
容量为C的缓冲管道:第k个接收happens-before第k+C个发送
Locks
n<m: 第n个Unlock() happens-before 第m个Lock()
Once
多个线程都可以执行once.Do(f),但是只有一个会运行f(),该f()的调用happens-before所有once.Do(f)的返回。
有疑问加站长微信联系(非本文作者)