Go语言中使用WaitGroup后仍出现goroutine死锁,原因何在?
问题分析与解决
你的代码触发死锁的核心原因在于通道未关闭导致读取goroutine无法退出,具体流程如下:
writeToChan完成5个元素的写入后,执行defer wg.Done()并结束自身goroutine。readToChan中的for range读取通道逻辑是:只要通道没关闭,就会一直阻塞等待新数据。当通道内的0-4全部读完后,通道处于无数据但未关闭的状态,readToChan会一直卡在循环里,永远无法执行defer wg.Done()。- main函数的
wg.Wait()始终在等待两个goroutine的Done信号,可readToChan永远发不出这个信号,导致main也陷入阻塞。 - 此时所有活跃goroutine(main和readToChan)都处于阻塞状态,没有任何goroutine能推进程序,最终触发死锁。
解决办法
在writeToChan写完所有数据后关闭通道,这样readToChan的for range会在通道关闭且剩余数据读完后自动退出循环,进而执行wg.Done(),让main函数的wg.Wait()正常结束。
修改后的writeToChan函数:
func writeToChan(wg *sync.WaitGroup, ch chan int, stop int) { defer wg.Done() for i := 0; i < stop; i++ { ch <- i } close(ch) // 写完所有数据后关闭通道 }
修改后程序会正常打印0-4,然后无报错退出。
内容的提问来源于stack exchange,提问作者Thai Nguyen
相关产品推荐
相关产品推荐

