go中的致命错误:陷入死锁
在一段go代码中,遇到错误提示“fatal error: all goroutines are asleep - deadlock!”,这表明程序陷入了一种死锁状态。
代码如下:
func main() { a := make(chan bool) b := make(chan bool) defer close(a) defer close(b) var wg sync.waitgroup wg.add(2) go func() { for i := 0; i < 10; i += 2 { if <-a { fmt.println(i) b <- true } } wg.done() }() go func() { for i := 1; i < 10; i += 2 { if <-b { fmt.println(i) a <- true } } wg.done() }() a <- true wg.wait() }
要解决这个问题,需要理解死锁是如何发生的。
代码中,两个goroutine交替从a和b通道中读写数据。问题出在b goroutine的最后一次写入a
要解决这个问题,可以在b goroutine中添加一次额外的从a通道读入操作:
func main() { A := make(chan bool) B := make(chan bool) defer close(A) defer close(B) var wg sync.WaitGroup wg.Add(2) go func() { for i := 0; i < 10; i += 2 { if <-A { fmt.Println(i) B <- true } } <-A // 添加这一行 wg.Done() }() go func() { for i := 1; i < 10; i += 2 { if <-B { fmt.Println(i) A <- true } } wg.Done() }() A <- true wg.Wait() }
添加这一行后,b goroutine在结束前会等待a通道中的最后一个值,避免死锁。
以上就是Go 中的致命错误:如何解决“fatal error: all goroutines are asleep - deadlock!”?的详细内容,更多请关注php中文网其它相关文章!
版权声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系 yyfuon@163.com