go WaitGroup的坑
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的坑相关推荐
- 社招,文章很细节,大家看下我有多细
社招面试 个人简介: 迅雷两年后台开发(偏业务方向) 熟悉go开发,理解go协程.channel.内存分配.GC等基本原理及部分源码 熟悉mysql.redis.leveldb,理解其基本原理及部分源 ...
- Golang中WaitGroup使用的一点坑
Golang中WaitGroup使用的一点坑 Golang 中的 WaitGroup 一直是同步 goroutine 的推荐实践.自己用了两年多也没遇到过什么问题.直到一天午睡后,同事扔过来一段奇怪的 ...
- golang 开发常见坑
目录 初级 开大括号不能放在单独的一行 未使用的变量 未使用的Imports 简式的变量声明仅可以在函数内部使用 使用简式声明重复声明变量 不能使用短变量声明来设置字段值 Can't Use Shor ...
- Golang 新手可能会踩的 50 个坑
前言 Go 是一门简单有趣的编程语言,与其他语言一样,在使用时不免会遇到很多坑,不过它们大多不是 Go 本身的设计缺陷.如果你刚从其他语言转到 Go,那这篇文章里的坑多半会踩到. 如果花时间学习官方 ...
- Go嵌套并发实现EDM,附坑点分析#1
看着身边优秀的小伙伴们早就开始写博客,自己深感落后,还好迟做总比不做好,勉励自己见贤思齐.趁着年前最后一个周末,阳光正好,写下第一篇博客,为2019年开个头,以期完成今年为自己立下的flags. 从P ...
- 从 bug 中学习:六大开源项目告诉你 go 并发编程的那些坑
作者:richardyao,腾讯 CSIG 后台开发工程师 并发编程中,go 不仅仅支持传统的通过共享内存的方式来通信,更推崇通过channel来传递消息,这种新的并发编程模型会出现不同于以往的bug ...
- Go的50坑:新Golang开发者要注意的陷阱、技巧和常见错误[1]
Go的50坑:新Golang开发者要注意的陷阱.技巧和常见错误[1] 初级篇 开大括号不能放在单独的一行 未使用的变量 未使用的Imports 简式的变量声明仅可以在函数内部使用 使用简式声明重复声明 ...
- [转载][翻译]Go的50坑:新Golang开发者要注意的陷阱、技巧和常见错误[1]
Golang作为一个略古怪而新的语言,有自己一套特色和哲学.从其他语言转来的开发者在刚接触到的时候往往大吃苦头,我也不例外.这篇文章很细致地介绍了Golang的一些常见坑点,读完全篇中枪好多次.故将其 ...
- go单元测试踩坑记录
Go踩坑记录 1. go单元测试 测试文件名字必须是xxx_test后缀 测试函数必须是Test开头(否则报错,no test to run) 1.1 gomock单元测试 gomock对接口进行打桩 ...
最新文章
- Javascript到PHP加密通讯的简单实现
- CentOS5.3编译安装mod_jk_1.2.15_链接器_整合apache_httpd和tomcat
- spring in action 4 第5章
- (十)Centos之文件搜索命令find
- 进程间共享内存(信号量实现同步)
- Android 开源框架Universal-Image-Loader完全解析(一)--- 基本介绍及使用
- 微信小程序 条形加载读取进度 切换音频进度。简单实现(自定义音频界面实现)
- [1197]约瑟夫问题 (循环链表)SDUT
- 浅析微信支付:申请退款、退款回调接口、查询退款
- 5.7和5.6的mysql_mysql5.6和5.7的区别
- session-path
- 惊叹jQuery(解决jQuery对象到DOM的转换)
- mysql索引or_mysql索引之or条件
- Rust: tokio,异步代码与运行速度初探
- 情人节,教你用Python定时给小姐姐微信发送专属问候!
- 老路《用得上的商学课》学习笔记(1-5课)
- Jmeter性能测试之测试报告
- 电压型逆变器和电流型逆变器的不同
- 名动漫原画“室内设计”-张聪-专题视频课程
- 淘宝员工感慨阿里没竞争力:百度24K,阿里30K,毫不犹豫选百度
热门文章
- QGridLayout比例
- OSPF Unicast Multicast and Network Type(OSPF的单播多播与网络类型辩析)
- [导入]关于复制目录架构
- 2021牛客多校6 - Hopping Rabbit(矩形取模+扫描线)
- HDU - 4784 Dinner Coming Soon(bfs+动态规划+优先队列)
- 安卓进阶系列-05列表控件(RecyclerView)的使用
- android 每分钟广播,每1分钟Android发布一次警报管理器?
- sqlite java blob_【转】好东西!sqlite3中BLOB数据类型存储大对象运用示例
- Win32多线程编程(2) — 线程控制
- ARP欺骗:先认识再防御