2 回答
TA贡献1877条经验 获得超6个赞
你的程序在所有 goroutine 完成之前就退出了。在从 返回之前,您需要等待 thefoo和bargoroutines 完成main。
执行此操作的通常方法是使用 a sync.WaitGroup,但由于main它不是d通道的生产者,因此您必须确保在使用第二个 WaitGroup(或等效项)关闭该通道之前完成该通道上的所有发送。
var (
fooWG sync.WaitGroup
barWG sync.WaitGroup
)
func main() {
d := make(chan uint)
barWG.Add(1)
go bar(d)
c1 := make(chan uint)
c2 := make(chan uint)
c3 := make(chan uint)
fooWG.Add(3)
go foo(c1, d)
go foo(c2, d)
go foo(c3, d)
c1 <- 1
c2 <- 2
c3 <- 3
c1 <- 4
c2 <- 5
c3 <- 6
c1 <- 7
c2 <- 8
c3 <- 9
// close the channels so the foo goroutines can exit
close(c1)
close(c2)
close(c3)
fooWG.Wait()
// all foo are done, so it's safe to close d and wait for bar
close(d)
barWG.Wait()
}
func foo(c chan uint, d chan uint) {
defer fooWG.Done()
fmt.Println("foo start")
for stuff := range c {
time.Sleep(1)
d <- stuff * 2
}
fmt.Println("foo end")
}
func bar(d chan uint) {
defer barWG.Done()
fmt.Println("bar start")
for stuff := range d {
fmt.Printf("bar received %d\n", stuff)
}
fmt.Println("bar end")
}
TA贡献1796条经验 获得超4个赞
JimB 的答案绝对有效,但它增加了比代码中实际需要的更多的复杂性。一个简单的完整通道就足以通过完成同步此代码。
此外,通过通道同步,time.Sleep(1)功能不再需要该命令:
package main
import (
"fmt"
"time"
)
func main() {
d := make(chan uint)
complete := make(chan bool)
go bar(d, complete)
c1 := make(chan uint)
c2 := make(chan uint)
c3 := make(chan uint)
go foo(c1, d)
go foo(c2, d)
go foo(c3, d)
c1 <- 1
c2 <- 2
c3 <- 3
c1 <- 4
c2 <- 5
c3 <- 6
c1 <- 7
c2 <- 8
c3 <- 9
//If you know the number of inputs, count them to ensure completion
for i:=0; i < 9; i++{
<-complete
}
//Clean up after yourself, to keep away the memory leaks
close(c1)
close(c2)
close(c3)
close(d)
//Verify bar is done and closed correctly
<-complete
close(complete)
}
func foo(c chan uint, d chan uint) {
fmt.Println("foo start")
for stuff := range c {
time.Sleep(1) //Not needed for the program to function
d <- stuff * 2
}
fmt.Println("foo end")
}
func bar(d chan uint, cmp chan bool) {
fmt.Println("bar start")
for stuff := range d {
fmt.Printf("bar received %d\n", stuff)
cmp <- true
}
fmt.Println("bar end")
//verify that cmp can be closed (all output is done, and d is closed)
cmp <- true
}
- 2 回答
- 0 关注
- 167 浏览
添加回答
举报