小伙伴们有没有觉得学习Golang很有意思?有意思就对了!今天就给大家带来《waitgroup.Wait() 导致死锁》,以下内容将会涉及到,若是在学习中对其中部分知识点有疑问,或许看了本文就能帮到你!
问题内容我试图找出为什么我与 waitgroup.wait() 发生死锁
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
func foo(c chan int, i int) {
defer wg.Done()
c <- i
}
func main() {
ch := make(chan int)
for i := 0; i < 10; i++ {
wg.Add(1)
go foo(ch, i)
}
wg.Wait()
close(ch)
for item := range ch {
fmt.Println(item)
}
}
当我像这样运行它时,它会打印 fatal error: all goroutine are sleep - deadlock!
我尝试将 ch
更改为缓冲通道,这解决了问题。但我很想知道为什么会出现死锁。
正确答案
我已经注释掉了你的程序逻辑不正确的部分:
package main
import (
"fmt"
"sync"
)
var wg sync.waitgroup
func foo(c chan int, i int) {
defer wg.done()
c <- i
}
func main() {
ch := make(chan int) // unbuffered channel
for i := 0; i < 10; i++ {
wg.add(1)
go foo(ch, i)
}
// wg.wait is waiting for all goroutines to finish but that's
// only possible if the send to channel succeeds. in this case,
// it is not possible as your receiver "for item := range ch" is below
// this. hence, a deadlock.
wg.wait()
// ideally, it should be the sender's duty to close the channel.
// and closing a channel before the receiver where the channel
// is unbuffered is not correct.
close(ch)
for item := range ch {
fmt.println(item)
}
}
更正的程序:
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
func foo(c chan int, i int) {
defer wg.Done()
c <- i
}
func main() {
ch := make(chan int)
go func() {
for item := range ch {
fmt.Println(item)
}
}()
for i := 0; i < 10; i++ {
wg.Add(1)
go foo(ch, i)
}
wg.Wait()
close(ch)
}
终于介绍完啦!小伙伴们,这篇关于《waitgroup.Wait() 导致死锁》的介绍应该让你收获多多了吧!欢迎大家收藏或分享给更多需要学习的朋友吧~编程网公众号也会发布Golang相关知识,快来关注吧!