Golang中能否使用select访问ch1、ch2通道?无打印输出问题排查
Go通道代码无输出问题解决方案
问题根因
你的代码没有输出是两个原因共同导致的:
- 主协程提前退出:Go程序的main函数执行完毕后,整个进程会直接终止,不会等待后台启动的goroutine执行完成。你在main函数中启动
CVIOgoroutine后没有任何等待逻辑,子协程还没来得及运行程序就已经退出。 - 无缓冲通道无对应操作方:你创建的ch1、ch2、quit都是无缓冲通道,
CVIO方法中的select三个分支分别是往ch1发数据、往ch2发数据、从quit收数据,由于没有其他goroutine执行对应的接收/发送操作,就算子协程能运行也会永久阻塞在select语句处,不会触发打印逻辑。
修复代码
package main import ( "fmt" "sync" ) type degen struct { i, j string } func (x degen) CVIO(ch1, ch2 chan string, quit chan int, m, n string, wg *sync.WaitGroup) { defer wg.Done() for { select { case ch1 <- m: fmt.Println(x.i) case ch2 <- n: fmt.Println("ok") case <-quit: fmt.Println("quit") return } } } func main() { ch1 := make(chan string) ch2 := make(chan string) quit := make(chan int) var wg sync.WaitGroup x := degen{"goosebump", "ok"} wg.Add(1) go x.CVIO(ch1, ch2, quit, "goosebump", "ok", &wg) // 执行通道接收操作,触发对应select分支 fmt.Println("ch1接收数据:", <-ch1) fmt.Println("ch2接收数据:", <-ch2) // 发送退出信号终止子协程循环 quit <- 1 // 等待子协程执行完成 wg.Wait() }
修复说明
- 引入
sync.WaitGroup组件实现主协程对子协程的等待,避免进程提前退出 - 新增了ch1、ch2的接收逻辑,让通道的发送操作可以正常完成,触发对应打印
- 最后向quit通道发送退出信号,正常结束子协程的循环逻辑
运行修复后的代码即可看到你期望的通道生产对应数据的打印效果。
内容的提问来源于stack exchange,提问作者Afzal Ansari
相关产品推荐
相关产品推荐

