2012-09-13 33 views
19

考慮下面這個簡單的圍棋程序扔:所有夠程都睡着了 - 死鎖

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! 

謝謝

回答

30

由於您從不關閉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

不直接相關的問題,但仍然是有趣的瞭解夠程:如果添加'fmt.Println(「退出總」)''後出< - res'你可能再也看不到它,因爲程序可能會更快退出,而無需等待goroutine完成。 –

+0

我開始學習前幾天,我不明白howcome res:= 0只運行一次?整個功能是否應該運行3次?在你的例子中,只有循環運行3次。 – if237912print

+0

@OybekToirov整個函數只運行一次,每次int'in'通道中有迭代時迭代進行 –

-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") 
} 
+3

這並不回答原始程序出了什麼問題。 –

相關問題