2014-10-04 76 views
2

本示例摘自http://blog.golang.org/pipelines。它運行並給出正確的答案,但它顯示以下運行時錯誤:「致命錯誤:所有goroutines睡着了 - 死鎖!」。任何人都可以幫助我理解爲什麼會發生? 包主以下golang代碼死鎖。有人可以幫助理解爲什麼嗎?

import (
    "fmt" 
) 

func gen(nums ...int) <- chan int { 
    out := make(chan int) 
    go func() { 
     for _, n := range nums { 
      out <- n 
     } 
    }() 
    return out 
} 

func sq(in <- chan int) <- chan int { 
    out := make(chan int) 
    go func() { 
     for n := range in { 
      out <- n * n 
     } 
     close(out) 
    }() 
    return out 
} 

func main() { 
    for n := range sq(gen(2,3)) { 
     fmt.Println(n) 
    } 
} 

但是,下面的修改沒有。

func main() { 
    // Set up the pipeline. 
    c := gen(2, 3) 
    out := sq(c) 

    // Consume the output. 
    fmt.Println(<-out) // 4 
    fmt.Println(<-out) // 9 
} 

回答

2

sq()函數的for n := range in從不退出,並啓動(後讀取2個值)阻擋,因爲gen()從未關閉了通道。
close(out)添加到go funcgen()將使其工作:see playground

使用通道,接收機阻塞直到接收到一個值。
The range keyword, when used with a channel, will wait on the channel until it is closed

sq()被阻塞,這意味着close(out)不會被調用,並依次main()塊上range sq()(因爲信道sq沒有關閉)。

在第二個示例中,main()本身已退出,這意味着即使sq()已被阻止,但所有內容仍會停止。

相關問題