Go语言通道传数据异常求助:为何数据无法抵达fmt.Println?
问题分析与解决方案
你的代码有几个关键问题导致数据无法传递到fmt.Println(<-c),咱们一个个拆解:
1. 无限循环让后续代码永远没机会执行
main函数里的for { ... }是个没有退出条件的死循环,它会一直霸占程序执行流,后面的fmt.Println(<-c)语句根本不可能被运行到——不管前面的逻辑有没有问题,这行代码都永远触达不了。
2. 无缓冲通道的发送阻塞,引发WaitGroup死锁
你创建的是无缓冲通道c := make(chan string),这类通道的发送操作c <- "test"必须等到有接收方准备好接收数据时,才能完成并往下执行。而你的代码逻辑里:
Avggoroutine启动后,立刻卡在c <- "test"上,等着有人来收数据maingoroutine则卡在wg.Wait()上,等着Avg执行完defer wg.Done()
两边互相等,直接形成死锁,程序第一次触发定时器后就彻底卡住了。
修复后的示例代码
这里给你调整了两种可行的修复方案:
方案一:保留WaitGroup,新增接收goroutine
package main import ( "fmt" "sync" "time" ) func Avg(c chan string, wg *sync.WaitGroup) { defer wg.Done() c <- "test" } func main() { var wg sync.WaitGroup c := make(chan string) timer1 := time.NewTicker(5 * time.Second) // 只执行一次定时器触发,去掉无限循环 select { case <-timer1.C: wg.Add(1) go Avg(c, &wg) // 单独开goroutine接收数据,避免发送阻塞 go func() { fmt.Println(<-c) }() wg.Wait() } timer1.Stop() }
方案二:用通道替代WaitGroup做同步(更简洁)
package main import ( "fmt" "time" ) func Avg(c chan string) { c <- "test" } func main() { c := make(chan string) timer1 := time.NewTicker(5 * time.Second) <-timer1.C go Avg(c) fmt.Println(<-c) // 直接接收通道数据,利用通道本身的同步特性 timer1.Stop() }
关键总结
- 无缓冲通道的发送和接收必须同时就绪,否则会阻塞;如果需要异步发送,可以考虑用带缓冲的通道(比如
make(chan string, 1)) - 避免无意义的无限循环,确保后续代码有执行机会
- 用WaitGroup配合通道时,要注意避免因通道阻塞导致的WaitGroup无法完成的死锁情况
内容的提问来源于stack exchange,提问作者Miha Zoubek
相关产品推荐
相关产品推荐

