Golang通道死锁问题排查:all goroutines are asleep报错
问题分析与修复
死锁原因
你的代码触发死锁的核心原因是无缓冲通道的阻塞特性:
outputStream是无缓冲通道,removeDuplicates在主goroutine中往这个通道写数据时,没有任何goroutine在读取它,导致outputStream <- i这一行直接阻塞removeDuplicates阻塞后,无法继续读取inputStream,而addvaluesInputStream作为goroutine往无缓冲的inputStream写数据时,因为没有接收方(removeDuplicates已经卡住),也会阻塞- 最终所有goroutine都处于阻塞状态,Go runtime检测到后抛出
all goroutines are asleep - deadlock错误
修复后的完整代码
把removeDuplicates放到goroutine中执行,同时在主goroutine里添加你计划的outputStream读取逻辑,确保通道的读写配对:
package main import ( "fmt" ) func addvaluesInputStream(inputStream chan string, str string) { for v := range str { l := string(str[v]) inputStream <- l } close(inputStream) } func removeDuplicates(inputStream, outputStream chan string) { var tmp string for i := range inputStream { if tmp != i { outputStream <- i tmp = i } } close(outputStream) } func main() { inputStream := make(chan string) outputStream := make(chan string) fmt.Println("Step 1") str := "8qqqqq1q12334Qtx" go addvaluesInputStream(inputStream, str) // 将去重逻辑放到goroutine中,避免阻塞主goroutine go removeDuplicates(inputStream, outputStream) // 读取outputStream,完成通道的消费 for n := range outputStream { fmt.Printf("%v", n) } fmt.Println() // 换行,让输出更整洁 }
运行结果
执行后会输出去重后的字符串:8q1q1234Qtx
内容的提问来源于stack exchange,提问作者Eugene Shlyapkin
相关产品推荐
相关产品推荐

