Go:死锁恐慌 - 了解原因并修复它
在 Go 中,遇到的常见错误是“致命错误:所有 goroutine 都睡着了——僵局!”当尝试管理 goroutine 之间的通信时。当 goroutine 陷入相互等待对方继续的状态时,就会出现此错误。
问题陈述
考虑以下您想要阅读的代码文本文件中的一行单词,将它们存储在通道中,然后打印它们分别:
func main() { f, _ := os.Open("D:\input1.txt") scanner := bufio.NewScanner(f) file1chan := make(chan string) for scanner.Scan() { line := scanner.Text() parts := strings.Fields(line) for i := range parts { file1chan <- parts[i] } } print(file1chan) } func print(in <-chan string) { for str := range in { fmt.Printf("%s\n", str) } }
死锁的原因
运行此代码时,您会遇到死锁错误。出现这种情况是因为通道 file1chan 未缓冲。因此,当您尝试将值发送到通道时,它会无限期地阻塞,等待接收者。
修复死锁
要解决死锁,你有两个选择:
使用缓冲通道:
您可以通过将其大小指定为 make(chan) 的第二个参数来创建缓冲通道,如下所示:
file1chan := make(chan string, 1) // buffer size of one
缓冲通道的作用类似于数组,其中如果通道有可用容量,发送者可以无阻塞地发送值。
使用新的Goroutine:
你可以启动一个新的goroutine来向无缓冲的通道发送值:
file1chan := make(chan string) go func() { // start a new goroutine that sends strings down file1chan for scanner.Scan() { line := scanner.Text() parts := strings.Fields(line) for i := range parts { file1chan <- parts[i] } } close(file1chan) }() print(file1chan)
通过这种方式,新的goroutine承担发送值的责任,而主goroutine则专注于
通过实施这些解决方案中的任何一个,您可以有效地消除僵局并使您的 goroutine 之间能够顺利通信。
以上是为什么 Go 程序会遇到'致命错误:所有 goroutine 都在睡眠 - 死锁!”以及如何修复?的详细内容。更多信息请关注PHP中文网其他相关文章!