Go语言如何先打印HELLO再输出错误信息并避免通道panic?
解决方案:调整Go代码执行顺序并避免通道panic
原代码的问题在于,主goroutine会阻塞在for item := range errorsChan循环上,直到通道关闭才会继续执行fmt.Print("HELLO\n"),导致错误信息先于HELLO输出。同时错误的WaitGroup管理会引发通道提前关闭的panic。
以下是修改后的代码,实现先输出HELLO,再打印错误信息,同时避免通道相关panic:
package main import ( "errors" "fmt" "sync" "time" er "github.com/pkg/errors" ) func main() { var wg sync.WaitGroup errorsChan := make(chan error) // 启动两个任务goroutine wg.Add(2) go func() { defer wg.Done() say(5) errorsChan <- er.Wrap(errors.New("first one"), "first test") }() go func() { defer wg.Done() say(1) errorsChan <- er.Wrap(errors.New("something"), "another test") }() // 单独goroutine:等待所有任务完成后关闭通道 go func() { wg.Wait() close(errorsChan) }() // 主goroutine先输出HELLO,不等待错误处理 fmt.Print("HELLO\n") // 单独goroutine处理错误输出,不阻塞主流程 go func() { for item := range errorsChan { fmt.Println(item) } }() // 等待所有错误处理完成(可选,若需要主goroutine不立即退出) wg.Wait() } func say(i time.Duration) { time.Sleep(i * time.Second) }
修改说明:
- 优先输出HELLO:主goroutine不再阻塞在错误通道的读取循环,直接先打印HELLO
- 独立错误处理goroutine:将错误信息的打印逻辑放到单独的goroutine中,不影响主流程的执行顺序
- 正确管理WaitGroup:直接为两个任务goroutine计数,确保所有发送错误的操作完成后才关闭通道,从根源避免
send on closed channelpanic - 无缓冲通道安全:即使使用无缓冲通道,由于错误读取goroutine一直在等待接收,发送操作不会阻塞或引发panic
内容的提问来源于stack exchange,提问作者HexaCrop
相关产品推荐
相关产品推荐

