sync.WaitGroup的使用以及坑
以及 Sync 使用
2023-09-14 09:12:11 时间
all goroutines are asleep - deadlock
简单使用:
package main
import (
"sync"
)
type httpPkg struct{}
func (httpPkg) Get(url string) {}
var http httpPkg
func main() {
var wg sync.WaitGroup
var urls = []string{
"http://www.golang.org/",
"http://www.google.com/",
"http://www.somestupidname.com/",
}
for _, url := range urls {
// Increment the WaitGroup counter.
wg.Add(1)
// Launch a goroutine to fetch the URL.
go func(url string) {
// Decrement the counter when the goroutine completes.
defer wg.Done()
// Fetch the URL.
http.Get(url)
}(url)
}
// Wait for all HTTP fetches to complete.
wg.Wait()
}
跟java的CountdownLatch
差不多,也是阻塞等待所有任务完成之后再继续执行。
简单使用就是在创建一个任务的时候wg.Add(1)
, 任务完成的时候使用wg.Done()
来将任务减一。使用wg.Wait()
来阻塞等待所有任务完成。
然后我就写了一个例子:
func main() {
var wg sync.WaitGroup
ch := make(chan int, 1000)
for i := 0; i < 1000; i++ {
wg.Add(1)
go doSomething(i, wg, ch)
}
wg.Wait()
fmt.Println("all done")
for i := 0; i < 1000; i++ {
dd := <-ch
fmt.Println("from ch:"+strconv.Itoa(dd))
}
}
func doSomething(index int, wg sync.WaitGroup, ch chan int) {
defer wg.Done()
fmt.Println("start done:" + strconv.Itoa(index))
//time.Sleep(20 * time.Millisecond)
ch <- index
}
然后就报错了:
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [semacquire]:
sync.runtime_Semacquire(0xc42001608c)
/usr/local/Cellar/go/1.10.3/libexec/src/runtime/sema.go:56 +0x39
sync.(*WaitGroup).Wait(0xc420016080)
/usr/local/Cellar/go/1.10.3/libexec/src/sync/waitgroup.go:129 +0x72
main.main()
/Users/taoli/go/src/github.com/c60/cai/tx_gorutine.go:16 +0xea
怎么回事,他说死锁了。
原来这是说,所有的协程都运行完了,你这边还在等待。
什么原因导致的呢?
原来是golang里如果方法传递的不是地址,那么就会做一个拷贝,所以这里调用的wg根本就不是一个对象。
传递的地方传递地址就可以了:
go doSomething(i, &wg, ch)
func doSomething(index int, wg *sync.WaitGroup, ch chan int) {
作者:ironman_
链接:https://www.jianshu.com/p/4c2c80076094
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
相关文章
- H7-TOOL发布固件V2.17, 脱机烧录增加泰为,华大和复旦微新系列以及串口和CANFD接口脱机烧录,LUA小程序实现JSCope HSS模式波形
- SpringBoot配置PageHelper分页插件以及配置MyBatis
- 【Django】当大型项目采用Django框架对于QueryDict以及模板的表单在Admin 管理工具的使用
- Portraiture专业的磨皮滤镜支持Ps以及Li软件插件
- 科普 | 什么是病毒以及 COVID-19 遗传易感性的研究
- SpringBoot2.5.1整合thymeleaf以及springsecurity后sec:authorize无效的问题
- 华为官宣:将于3月23日发布P60系列以及Mate X3等
- Oracle数据库中的控制文件管理以及常用参数设置
- 每周开源点评:云原生 Java、开源安全以及更多行业趋势
- 「MySQL判断字符串长度」,学会字符长度函数LENGTH、CHAR_LENGTH以及使用注意事项。(mysql判断长度)
- 深入探讨:oracle中方案的概念以及方案与数据库的关系