Go 当通过通道接收值时,为什么看不到输出
在下一个示例中,我不明白为什么接收时未打印结束值Go 当通过通道接收值时,为什么看不到输出,go,concurrency,Go,Concurrency,在下一个示例中,我不明白为什么接收时未打印结束值 package main import "fmt" func main() { start := make(chan int) end := make(chan int) go func() { fmt.Println("Start") fmt.Println(<-start) }() go func() { fmt.Println("End")
package main
import "fmt"
func main() {
start := make(chan int)
end := make(chan int)
go func() {
fmt.Println("Start")
fmt.Println(<-start)
}()
go func() {
fmt.Println("End")
fmt.Println(<-end)
}()
start <- 1
end <- 2
}
我知道sync.WaitGroup可以解决这个问题 因为程序在到达func main末尾时退出,而不管是否有其他goroutine正在运行。一旦第二个函数从结束通道接收到消息,main在该通道上的发送即被解除阻止,程序完成,在接收到的值有机会传递给Println之前。未打印结束值,因为一旦主goroutine(主函数实际上是goroutine)完成,其他非主goroutine就没有机会完成 当函数main返回时,程序退出。此外,goroutine是独立的执行单元,当许多goroutine一个接一个地启动时,您不能依赖goroutine实际启动的时间。代码的逻辑必须独立于调用goroutine的顺序 解决你的问题的一个方法,也是最简单的一个方法,就是在你的主要功能的末尾放一个时间
time.Sleep(1e9)
这将保证主goroutine不会解除阻止,而其他goroutine将有一个更改来执行
package main
import (
"fmt"
"time"
)
func main() {
start := make(chan int)
end := make(chan int)
go func() {
fmt.Println("Start")
fmt.Println(<-start)
}()
go func() {
fmt.Println("End")
fmt.Println(<-end)
}()
start <- 1
end <- 2
time.Sleep(1e9)
}
您提到的另一个解决方案是使用waitgroup。除了必须指定时间的sleep之外,还可以使用waitgroup让程序等待goroutine完成执行
package main
import "fmt"
import "sync"
var wg sync.WaitGroup
func main() {
start := make(chan int)
end := make(chan int)
wg.Add(2)
go func() {
defer wg.Done()
fmt.Println("Start")
fmt.Println(<-start)
}()
go func() {
defer wg.Done()
fmt.Println("End")
fmt.Println(<-end)
}()
start <- 1
end <- 2
wg.Wait()
}