并发中的死锁错误:“抛出:所有 Goroutine 都处于睡眠状态”
在 Go 中处理并发时,如果所有 Goroutines 都处于休眠状态,则可能会发生死锁goroutine 正在等待彼此执行操作。与此问题相关的一个常见错误是“抛出:所有 goroutine 都在睡眠 - 死锁!”
理解问题
考虑以下 Go 程序:
package main import ( "fmt" ) func total(ch chan int) { res := 0 for iter := range ch { res += iter } ch <- res } func main() { ch := make(chan int) go total(ch) ch <- 1 ch <- 2 ch <- 3 fmt.Println("Total is ", <-ch) }
运行这个程序时,我们遇到错误“throw: all goroutine are sleep - deadlock!”原因是total函数中的范围循环永远不会退出,因为我们永远不会关闭ch通道。结果,在 main 函数中等待接收结果的 goroutine 永远不会收到它。
解决死锁
要解决这个死锁,我们需要关闭ch 通道指示不再发送任何值。此外,我们可以使用单独的通道发送回结果,从而防止在同一通道上直接发送和接收。
下面修改后的程序解决了这些问题:
package main import ( "fmt" ) func total(in chan int, out chan int) { res := 0 for iter := range in { res += iter } out <- res // sends back the result } func main() { ch := make(chan int) rch := make(chan int) go total(ch, rch) ch <- 1 ch <- 2 ch <- 3 close(ch) // this will end the loop in the total function result := <-rch // waits for total to give the result fmt.Println("Total is ", result) }
通过关闭ch 通道并使用单独的 rch 通道来获取结果,我们消除了死锁并允许程序正确执行。
以上是如何解决 Go 并发死锁:'所有 goroutine 都在睡觉”?的详细内容。更多信息请关注PHP中文网其他相关文章!