注:本文已发布超过一年,请注意您所使用工具的相关版本是否适用
本系列为 Go 进阶训练营 笔记,访问 博客: Go进阶训练营, 即可查看当前更新进度,部分文章篇幅较长,使用 PC 大屏浏览体验更佳。
在上一篇文章《Week03: Go 并发编程(七) 深入理解 errgroup》当中看 errgourp 源码的时候我们发现最后返回 err 是通过 once 来只保证返回一个非 nil 的值的,本文就来看一下 Once 的使用与实现
once 的使用很简单
1 | |
输出
1 | |
1 | |
done 用于判定函数是否执行,如果不为 0 会直接返回
1 | |
看 go 的源码真的可以学到很多东西,在这里还给出了很容易犯错的一种实现
1 | |
如果这么实现最大的问题是,如果并发调用,一个 goroutine 执行,另外一个不会等正在执行的这个成功之后返回,而是直接就返回了,这就不能保证传入的方法一定会先执行一次了
所以回头看官方的实现
1 | |
会先判断 done 是否为 0,如果不为 0 说明还没执行过,就进入 doSlow
1 | |
在 doSlow 当中使用了互斥锁来保证只会执行一次
注:本文已发布超过一年,请注意您所使用工具的相关版本是否适用
本系列为 Go 进阶训练营 笔记,访问 博客: Go进阶训练营, 即可查看当前更新进度,部分文章篇幅较长,使用 PC 大屏浏览体验更佳。
在上一篇文章《Week03: Go 并发编程(七) 深入理解 errgroup》当中看 errgourp 源码的时候我们发现最后返回 err 是通过 once 来只保证返回一个非 nil 的值的,本文就来看一下 Once 的使用与实现
once 的使用很简单
1 | |
输出
1 | |
1 | |
done 用于判定函数是否执行,如果不为 0 会直接返回
1 | |
看 go 的源码真的可以学到很多东西,在这里还给出了很容易犯错的一种实现
1 | |
如果这么实现最大的问题是,如果并发调用,一个 goroutine 执行,另外一个不会等正在执行的这个成功之后返回,而是直接就返回了,这就不能保证传入的方法一定会先执行一次了
所以回头看官方的实现
1 | |
会先判断 done 是否为 0,如果不为 0 说明还没执行过,就进入 doSlow
1 | |
在 doSlow 当中使用了互斥锁来保证只会执行一次