go WaitGroup的使用请参考笔者的另外一篇博客

go WaitGroup的使用示例

这里重点讲一下WaitGroup的注意点,以免被坑

示例代码如下:

package main
import ("log""sync"
)
func main() {wg := sync.WaitGroup{}for i := 0; i < 5; i++ {wg.Add(1)go func(wg sync.WaitGroup, i int) {log.Printf("i:%d", i)wg.Done()}(wg, i)}wg.Wait()log.Println("exit")
}

代码很简单,主协程中新建5个子协程,每个子协程中打印数字后即结束,调用Done(),按照我们的代码执行应该是子协程打印参数后,主协程Wait()结束,打印exit,最终结束

但实际上执行结果却是下面:

竟然出错了!!!!!

是因为子协程函数的参数sync.WaitGroup,我们传入的是对象,是wg的新构造的临时对象,而非指针,所以Done()是在那个新的对象中执行的,而非我们的全局变量wg,所以全局变量wg没有子线程Done(),一直等待,造成了死锁

其实代码写完后,智能的编译器已经给出了提示,请看下图

请看弹框的内容,即sync.WaitGroup是不可拷贝构造的

所以我们把参数由对象改为指针时,即可修复

代码及执行效果如下:

package main
import ("log""sync"
)
func main() {wg := sync.WaitGroup{}for i := 0; i < 5; i++ {wg.Add(1)go func(wg *sync.WaitGroup, i int) {log.Printf("i:%d", i)wg.Done()}(&wg, i)}wg.Wait()log.Println("exit")
}

go WaitGroup的坑相关推荐

  1. 社招,文章很细节,大家看下我有多细

    社招面试 个人简介: 迅雷两年后台开发(偏业务方向) 熟悉go开发,理解go协程.channel.内存分配.GC等基本原理及部分源码 熟悉mysql.redis.leveldb,理解其基本原理及部分源 ...

  2. Golang中WaitGroup使用的一点坑

    Golang中WaitGroup使用的一点坑 Golang 中的 WaitGroup 一直是同步 goroutine 的推荐实践.自己用了两年多也没遇到过什么问题.直到一天午睡后,同事扔过来一段奇怪的 ...

  3. golang 开发常见坑

    目录 初级 开大括号不能放在单独的一行 未使用的变量 未使用的Imports 简式的变量声明仅可以在函数内部使用 使用简式声明重复声明变量 不能使用短变量声明来设置字段值 Can't Use Shor ...

  4. Golang 新手可能会踩的 50 个坑

    前言 Go 是一门简单有趣的编程语言,与其他语言一样,在使用时不免会遇到很多坑,不过它们大多不是 Go 本身的设计缺陷.如果你刚从其他语言转到 Go,那这篇文章里的坑多半会踩到. 如果花时间学习官方 ...

  5. Go嵌套并发实现EDM,附坑点分析#1

    看着身边优秀的小伙伴们早就开始写博客,自己深感落后,还好迟做总比不做好,勉励自己见贤思齐.趁着年前最后一个周末,阳光正好,写下第一篇博客,为2019年开个头,以期完成今年为自己立下的flags. 从P ...

  6. 从 bug 中学习:六大开源项目告诉你 go 并发编程的那些坑

    作者:richardyao,腾讯 CSIG 后台开发工程师 并发编程中,go 不仅仅支持传统的通过共享内存的方式来通信,更推崇通过channel来传递消息,这种新的并发编程模型会出现不同于以往的bug ...

  7. Go的50坑:新Golang开发者要注意的陷阱、技巧和常见错误[1]

    Go的50坑:新Golang开发者要注意的陷阱.技巧和常见错误[1] 初级篇 开大括号不能放在单独的一行 未使用的变量 未使用的Imports 简式的变量声明仅可以在函数内部使用 使用简式声明重复声明 ...

  8. [转载][翻译]Go的50坑:新Golang开发者要注意的陷阱、技巧和常见错误[1]

    Golang作为一个略古怪而新的语言,有自己一套特色和哲学.从其他语言转来的开发者在刚接触到的时候往往大吃苦头,我也不例外.这篇文章很细致地介绍了Golang的一些常见坑点,读完全篇中枪好多次.故将其 ...

  9. go单元测试踩坑记录

    Go踩坑记录 1. go单元测试 测试文件名字必须是xxx_test后缀 测试函数必须是Test开头(否则报错,no test to run) 1.1 gomock单元测试 gomock对接口进行打桩 ...

最新文章

  1. Javascript到PHP加密通讯的简单实现
  2. CentOS5.3编译安装mod_jk_1.2.15_链接器_整合apache_httpd和tomcat
  3. spring in action 4 第5章
  4. (十)Centos之文件搜索命令find
  5. 进程间共享内存(信号量实现同步)
  6. Android 开源框架Universal-Image-Loader完全解析(一)--- 基本介绍及使用
  7. 微信小程序 条形加载读取进度 切换音频进度。简单实现(自定义音频界面实现)
  8. [1197]约瑟夫问题 (循环链表)SDUT
  9. 浅析微信支付:申请退款、退款回调接口、查询退款
  10. 5.7和5.6的mysql_mysql5.6和5.7的区别
  11. session-path
  12. 惊叹jQuery(解决jQuery对象到DOM的转换)
  13. mysql索引or_mysql索引之or条件
  14. Rust: tokio,异步代码与运行速度初探
  15. 情人节,教你用Python定时给小姐姐微信发送专属问候!
  16. 老路《用得上的商学课》学习笔记(1-5课)
  17. Jmeter性能测试之测试报告
  18. 电压型逆变器和电流型逆变器的不同
  19. 名动漫原画“室内设计”-张聪-专题视频课程
  20. 淘宝员工感慨阿里没竞争力:百度24K,阿里30K,毫不犹豫选百度

热门文章

  1. QGridLayout比例
  2. OSPF Unicast Multicast and Network Type(OSPF的单播多播与网络类型辩析)
  3. [导入]关于复制目录架构
  4. 2021牛客多校6 - Hopping Rabbit(矩形取模+扫描线)
  5. HDU - 4784 Dinner Coming Soon(bfs+动态规划+优先队列)
  6. 安卓进阶系列-05列表控件(RecyclerView)的使用
  7. android 每分钟广播,每1分钟Android发布一次警报管理器?
  8. sqlite java blob_【转】好东西!sqlite3中BLOB数据类型存储大对象运用示例
  9. Win32多线程编程(2) — 线程控制
  10. ARP欺骗:先认识再防御