2 回答
TA贡献1811条经验 获得超5个赞
您的 WaitGroup.Add 和 WaitGroup.Done 调用不匹配。然而,在这种情况下,“我完成了”信号通常是通过关闭输出通道来给出的。仅当工作在多个 goroutine 之间共享时才需要 WaitGroups(即多个 goroutine 消耗相同的通道),但这里的情况并非如此。
package main
import (
"fmt"
)
func main() {
a1 := []string{"apple", "apricot"}
chan1 := make(chan string)
chan2 := make(chan string)
chan3 := make(chan string)
go func() {
for _, s := range a1 {
chan1 <- s
}
close(chan1)
}()
go Pipe1(chan2, chan1)
go Pipe2(chan3, chan2)
// This range loop terminates when chan3 is closed, which Pipe2 does after
// chan2 is closed, which Pipe1 does after chan1 is closed, which the
// anonymous goroutine above does after it sent all values.
for s := range chan3 {
fmt.Println(s)
}
}
func Pipe1(out chan<- string, in <-chan string) {
for s := range in {
out <- s + "s are"
}
close(out) // let caller know that we're done
}
func Pipe2(out chan<- string, in <-chan string) {
for s := range in {
out <- s + " good for you"
}
close(out) // let caller know that we're done
}
在操场上尝试一下:https ://play.golang.org/p/d2J4APjs_lL
TA贡献1820条经验 获得超2个赞
您正在调用wg.Wait
一个 goroutine,因此main
可以在其他例程完成之前返回(因此您的程序退出)。这会导致您看到的行为,但仅从 Goroutine 中取出是不够的。
您还滥用了WaitGroup
一般性;你的Add
和Done
调用 彼此不相关,并且你没有那么多Done
s Add
,所以 sWaitGroup
永远不会完成。如果您在循环中调用Add
,则每次循环迭代也必须导致调用Done
;正如您现在所拥有的,您defer wg.Done()
在每个循环之前,然后Add
在循环内部调用,从而产生一个Done
和多个Add
s。该代码需要进行重大修改才能按预期工作。
- 2 回答
- 0 关注
- 102 浏览
添加回答
举报