扔:所有的goroutines都睡着了 - 僵局

时间:2012-09-13 01:51:41

标签: multithreading go deadlock channel

给出以下简单的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 goroutines are asleep - deadlock!

谢谢

2 个答案:

答案 0 :(得分:32)

由于您从未关闭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)
}

答案 1 :(得分:-3)

这也是对的。

package main

import "fmt"

func main() {
    c := make(chan int)
    go do(c)
    c <- 1
    c <- 2
    // close(c)
    fmt.Println("Total is ", <-c)
}

func do(c chan int) {
    res := 0
    // for v := range c {
    //  res = res + v
    // }
    for i := 0; i < 2; i++ {
        res += <-c
    }
    c <- res
    fmt.Println("something")
}