我尝试用 channel 写一些 goroutine,但是死锁了,为什么? 我对WaitGroup做错了吗,很困惑...
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
func main() {
chan1 := make(chan string)
chan2 := make(chan string)
chan3 := make(chan string, 2)
wg.Add(1)
go makeChanStr("yeye", chan1, chan3)
wg.Add(1)
go makeChanStr("okok", chan2, chan3)
wg.Wait()
close(chan3)
println(<-chan1)
println(<-chan2)
for chs := range chan3 {
println(chs)
}
}
func makeChanStr(s string, c1 chan string, c2 chan string) {
defer wg.Done()
c1 <- "get " + s
c2 <- "same value"
fmt.Printf("execute ok %s", s)
}
Stackoverflow 只是不让我提交问题......所以我只需要添加一些文本......
答案 0 :(得分:4)
wg.Wait()
上的主块,等待这两个 goroutine 完成(因为 wg.Add(1)
和 wg.Done()
)
go makeChanStr("yeye", chan1, chan3)
go makeChanStr("okok", chan2, chan3)
但它们在 chan1
(或 chan2
)上阻塞,因为它是一个无缓冲通道。
chan1 := make(chan string)
尝试将 chan1
和 chan2
更改为缓冲通道:
chan1 := make(chan string,1)
chan2 := make(chan string,1)
答案 1 :(得分:1)
此代码在主协程中的 wg.Wait()
上阻塞,并在工作进程中写入 c1
。为避免这种情况 - 在 c1
之前从 c2
和 wg.Wait()
读取,从而解除对 worker 的阻塞,并且它们不会在写入缓冲的 c3
时阻塞。因此,wg.Done()
将被调用,wg.Wait()
也不会阻塞 main goroutine。
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
func main() {
chan1 := make(chan string)
chan2 := make(chan string)
chan3 := make(chan string, 2)
wg.Add(1)
go makeChanStr("yeye", chan1, chan3)
wg.Add(1)
go makeChanStr("okok", chan2, chan3)
println(<-chan1)
println(<-chan2)
wg.Wait()
close(chan3)
for chs := range chan3 {
println(chs)
}
}
func makeChanStr(s string, c1 chan string, c2 chan string) {
defer wg.Done()
c1 <- "get " + s
c2 <- "same value"
fmt.Printf("execute %s\n", s)
}