wait_group

sync.WaitGroup 类型是并发安全的,也是开箱就能用的。 该类型有三个指针方法,即:Add,Done和Wait.

sync.WaitGroup是一个结构体类型。其中一个代表计数的字节数组类型的字段,该 字段用4字节表示给定计数,另4字节表示等待计数。当一个sync.WaitGroup类型的变 量被声明之后,其中的这两个计数都会是0。可以通过add方法增大或减少其中给定计数, 例如:

wg.Add()
wg.Add(-)
需要注意的是,我们不能让这个计数值变成一个负数。
wg.Done()

相当于

wg.Add(-)

我们知道add和done方法可以变更计数器的值,但是变更之后具体有什么 作用呢?

当调用sync.WaitGroup类型值的Wait方法时,它会去检查给定计数。如果 该计数为0,那么该方法会立即返回,且不会对程序产生任何影响。但是, 如果这个计数器大于0,该方法调用所在的那个goroutine就会阻塞,同时 等待计数器会加1。直到在该值的add或done方法被调用时给定计数变回0. 该值才会去唤醒因此等待而阻塞的所有goroutine,同时清零等待计数。

现在我们有一个案例: 假设程序启用了4个goroutine,分别是g1,g2,g3,g4。其中g2,g3,g4是由代码g1 启用的,g1启用之后并且要等待这些特殊任务的完成。

使用通道来进行阻塞

  sign := make(chan int, )
go func() {
sign <-
fmt.Println()
}()
go func() {
sign <-
fmt.Println()
}() go func() {
sign <-
fmt.Println()
}() for i := ; i < ; i++ {
fmt.Println("执行", <-sign)
}
使用通道的有过于繁重了,原则上,我们不应该把通道当做互斥锁或信号量来使用。

使用waitGroup

var wg sync.WaitGroup

    wg.Add()
go func() {
wg.Done()
fmt.Println()
}()
go func() {
wg.Done()
fmt.Println()
}()
go func() {
wg.Done()
fmt.Println()
}() wg.Wait()
fmt.Println("1 2 3 4 end")

参考:go并发编程实战

最新文章

  1. ios开发之数据存储
  2. webapi同一个Controller多个函数
  3. lua cURL使用笔记
  4. PHP 递归的密码
  5. 在ubuntu(linux)下安装vim,以及vim的常用命令
  6. [原创] - C#编程大幅提高OUTLOOK的邮件搜索能力!
  7. Linux shell 脚本攻略之生成任意大小的文件
  8. hdu 4715 Difference Between Primes(素数筛选+树状数组哈希剪枝)
  9. 简洁代码---python---string
  10. 转:cookie和session(二)——php应用
  11. SuperSocket学习笔记(二)
  12. Angular Universal(统一平台)笔记
  13. oracle服务的一些问题,先发2个,以后慢慢添加~~
  14. 转:Git Submodule管理项目子模块
  15. Angular 基本内置服务和筛选器
  16. 初学cdq分治学习笔记(可能有第二次的学习笔记)
  17. 关于noip2017的感想
  18. 记OI退役
  19. 【impala学习之一】impala
  20. Git(二)使用git管理文件版本(TortoiseGit )

热门文章

  1. Centos7安装Elasticsearch和Kibana
  2. Spring Cloud 系列之 Netflix Hystrix 服务容错
  3. NodeMCU入坑指南-烧写固件并连接WIFI
  4. Nginx | CentOS 8 安装Nginx详细教程
  5. 如何删除Python中文本文件的文件内容?
  6. 解决pycharm不能导入bs4模块问题
  7. SpringCloud服务的注册发现--------Eureka
  8. ehcahe + redis 实现多级缓存
  9. php _weakup()反序列化漏洞
  10. iOS 响应链