Happen before定义

In the following descriptions, if we say event A is guaranteed to happen before event B, it means any of the goroutines involved in the two events will observe that any of the statements presented before event A in source code will be executed before any of the statements presented after event B in source code. For other irrelevant goroutines, the observed orders may be different from the just described.

首先happen before语义针对的是相关的协程,非相关协程观察到的顺序可以是不一样的;

其次,如果A语句happen before B语句,那么B语句之后一定能观察到所有A语句之前的语句;

不相关协程的例子

func f4() {var a, b, x, y intc := make(chan bool)go func() {a = 1c <- truex = 1}()go func() {b = 1<-cy = 1}()// Many data races are in this goroutine.// Don't write code as such.go func() {if x == 1 {if a != 1 { // possiblepanic("a != 1") // may happen}if b != 1 { // possiblepanic("b != 1") // may happen}}if y == 1 {if a != 1 { // possiblepanic("a != 1") // may happen}if b != 1 { // possiblepanic("b != 1") // may happen}}}()
}

Here, for the third goroutine, which is irrelevant to the operations on channel c. It will not be guaranteed to observe the orders observed by the first two new created goroutines. So, any of the four panic calls may get executed.

第三个协程没有channel(这里的channel是一个happen before语音,后文中所有提到的happen before语义均在这儿适用),所以它观察到的变量赋值顺序可能和有happen before语义中的协程中不同。

相关语法

goroutine创建

The creation of a goroutine happens before the execution of the goroutine

创建协程语句happen before被创建协程的执行

channel

1 The nth successful send to a channel happens before the nth successful receive from that channel completes, no matter that channel is buffered or unbuffered.(无论channel是否有capacity,对同一个数据的操作,将该数据push进channel happen before从该channel中读取到该数据)

2 The nth successful receive from a channel with capacity m happens before the (n+m)th successful send to that channel completes. In particular, if that channel is unbuffered (m == 0), the nth successful receive from that channel happens before the nth successful send on that channel completes.(如果一个channel的capacity为m,那么第n次接受到channel中的数据happen before第m+n次向channel中push数据。特例情况,若该channel的capacity=0,那么接受到数据的操作happen before向channel中push同一数据的操作。与之前的定义相结合,对于不带buffer的channel,push和pull操作互为happen before,它们被认为是一对同步事件。另一种解释是 开始发送 happen before 接受完成,开始接受 happen before 发送完成)

3 The closing of a channel happens before a receive completes if the receive returns a zero value because the channel is closed.(对于channel的关闭happen before接收到该关闭消息)

mutex

1 For an addressable value m of type Mutex or RWMutex in the sync standard package, the nth successful m.Unlock() method call happens before the (n+1)th m.Lock() method call returns.(第n次的unlock操作 happen before第n+1次lock操作)

2 For an addressable value rw of type RWMutex, if its nth rw.Lock() method call has returned, then its successful nth rw.Unlock() method call happens before the return of any rw.RLock() method call which is guaranteed to happen after the nth rw.Lock() method call returns.(对于读写锁,一旦写锁操作成功,那么它对应的unlock操作happen before所有随后的读锁)

3 For an addressable value rw of type RWMutex, if its nth rw.RLock() method call has returned, then its mth successful rw.RUnlock() method call, where m <= n, happens before the return of any rw.Lock() method call which is guaranteed to happen after the nth rw.RLock() method call returns.(对于读写锁,当第n次的读锁加锁成功,那么所有之前加锁成功的读锁对应的解锁操作,happen before随后的写锁加锁成功)

sync.WaitGroup

At a given time, assume the counter maintained by an addressable sync.WaitGroup value wg is not zero. If there is a group of wg.Add(n) method calls invoked after the given time, and we can make sure that only the last returned call among the group of calls will modify the counter maintained by wg to zero, then each of the group of calls is guaranteed to happen before the return of a wg.Wait method call which is invoked after the given time.

所有的wg.Add操作都happen before wg.Wait语句返回

sync.Once

Among these o.Do method calls, only exact one argument function will be invoked. The invoked argument function is guaranteed to exit before any o.Do method call returns. In other words, the code in the invoked argument function is guaranteed to be executed before any o.Do method call returns.

被实际调用的o.Do函数一定happen before所有调用o.Do函数返回之前

程序初始化

程序的初始化是发生在一个goroutine内的,这个goroutine可以创建多个新的goroutine,创建的goroutine和当前的goroutine可以并发的运行。

如果在一个goroutine所在的源码包p里面通过import命令导入了包q,那么q包里面go文件的初始化方法的执行会happens before 于包p里面的初始化方法执行。

Main package的init函数happen before main函数的执行

参考资料

Memory Order Guarantees in Go - Go 101: an online Go programming book + knowledge base

GoLang内存模型 - 云+社区 - 腾讯云

Golang happen before相关推荐

  1. 内存模型-Memory Model

    文章目录 1.1 CPU Cache 的产生背景 1.2 CPU Cache 模型 1.3 什么是 Cache Line 1.4 Flase Sharing 问题 1.5 CPU 缓存一致性协议 1. ...

  2. golang int64转string_Golang 并发数据冲突检测器与并发安全

    介绍 共享数据竞争问题是并发系统中常见且难排查的问题. 什么是数据竞争? 当两个协程goroutine同时访问相同的共享变量,其中有一个执行了写操作,或两个都执行了写操作,就会出现数据竞争问题,导致数 ...

  3. golang异步协程调度原理

    golang异步协程调度 在1.14的go版本中,官方通过加入信号来进行协程的调度,后续就都支持了这种异步协程抢占,避免了早起的考栈调度时来检查是否执行超时的逻辑.本文简单来对比这种实现的原理. 调度 ...

  4. golang垃圾回收概述

    golang垃圾回收 golang的垃圾回收机制已经迭代过好几次了,主要的几个演进过程如下: v1.0版本中使用标记和清除算法,需要再整个gc过程中暂定程序. V1.5版本中实现了三色标记清除的并发垃 ...

  5. golang源码分析-调度概述

    golang源码分析-调度过程概述 本文主要概述一下golang的调度器的大概工作的流程,众所周知golang是基于用户态的协程的调度来完成多任务的执行.在Linux操作系统中,以往的多线程执行都是通 ...

  6. golang的临时对象池sync.Pool

    今天在写码之时,发现了同事用到了sync.pool.因不知其因,遂Google之.虽然大概知道其原因和用法.还不能融汇贯通.故写此记,方便日后查阅.直至明了. 正文 在高并发或者大量的数据请求的场景中 ...

  7. Go Code Review Comments 翻译 编写优雅golang代码

    Gofmt 在 Go 代码上运行 gofmt 以自动修复大多数的机械性风格问题.几乎所有不正规的 Go 代码都在使用gofmt.本文档的剩余部分涉及非机械性风格问题. 另一种方法是使用 goimpor ...

  8. golang byte转string_Golang和Rust语言常见功能/库

    时下最流行.最具发展前途的的两门语言是Golang和Rust.Golang语言简洁.高效.并发.并且有个强大的囊括了常见功能标准库.与之相对比,Rust语言则主要是安全.高性能.虽然Rust没有gol ...

  9. Golang垃圾回收机制(一)

    原文: http://legendtkl.com/2017/04/28/golang-gc/ 1. Golang GC 发展 Golang 从第一个版本以来,GC 一直是大家诟病最多的.但是每一个版本 ...

  10. Golang源码探索(三) GC的实现原理

    Golang从1.5开始引入了三色GC, 经过多次改进, 当前的1.9版本的GC停顿时间已经可以做到极短. 停顿时间的减少意味着"最大响应时间"的缩短, 这也让go更适合编写网络服 ...

最新文章

  1. springmvc 音频流输出_音频管理模块AudioDeviceModule解读
  2. android 输入法遮挡布局解决方案
  3. LSTM时间序列预测及网络层搭建
  4. 最长上升子序列(LIS)的求法
  5. C#模板编程(1):有了泛型,为什么还需要模板?
  6. 《A First Course in Probability》-chape4-离散型随机变量-几种典型分布列
  7. Spring 国际化 MessageSource
  8. struts2.xml中使用chain和redirectAction这两个注意事项
  9. Welcome to Apache HBase 介绍一
  10. 变电站红外图像数据集
  11. 程序员们都用什么记笔记软件?
  12. 【挖坑记】JZOJ 4722 跳楼机
  13. C/C++笔试题(很多)
  14. mysql保存为vna文件_微机 模拟试题三(含答案)
  15. 漫谈阿里那些大数据技术,大数据学习者必看
  16. xms应用框架 - 基于.netcore
  17. 计算机网络互连基础技术及实战
  18. linux重启文件被删除,linux 误删文件恢复方法(debugfs)
  19. 开发中常见的一些插件收藏
  20. 熊市中,值得关注的项目都有这三大特征

热门文章

  1. 【渝粤教育】国家开放大学2018年秋季 1289T中国当代文学专题 参考试题
  2. stm32f103c8t6视频教程
  3. 【C语言学习】————操作符、关键字
  4. 【CF487E】Tourists
  5. 内网liunx环境升级nginx版本(因为nginx 0.6.x < 1.20.1 1-Byte Memory Overwrite RCE 系统漏洞而升级)
  6. 得知大熊哥最后一天在岗位工作今天离开有感而发
  7. 苹果恢复出厂设置系统也会还原吗_手机经常恢复出厂设置会怎么样?对手机有害处吗?这下终于清楚了...
  8. Linux下的sock_stream和sock_dgram
  9. 单目3D多人姿态估计网络(整合自上而下和自下而上网络)
  10. Vue报错Invalid handler for event “click“: got undefined的原因及解决办法