2017-02-09 66 views
0

我已經寫了一些代碼示例從GO Concurrencyfor循環造成僵局

func gen(numbers ...int) <-chan int { 
    out := make(chan int) 

    go func() { 
     for _, number := range numbers { 
      out <- number 
     } 
     close(out) 
    }() 

    return out 
} 

func sq(in <-chan int) <-chan int { 
    out := make(chan int) 

    go func() { 
     for number := range in { 
      out <- number * number 
     } 
    }() 

    return out 
} 

所以我想在我的主函數中使用上面的代碼是這樣的:

func main() { 



    result := sq(sq(sq(gen(1, 2, 3, 4)))) 

    fmt.Println(<-result) 
    fmt.Println(<-result) 
    fmt.Println(<-result) 
    fmt.Println(<-result) 

    fmt.Println("-------------------") 

    for channelValue := range sq(sq(sq(gen(1, 2, 3, 4)))) { 
     fmt.Println(channelValue) 
    } 

} 

我很困惑,當我運行代碼我得到這個消息後循環:

fatal error: all goroutines are asleep - deadlock

請幫我理解這一點。據我所知,調用fmt.Prinlnt(result) x 4次與for channelValue := range sq(sq(sq(gen(1, 2, 3, 4))))上的for循環相同。它是否正確?

請告訴我爲什麼我在循環後出現死鎖?

回答

2

在通道塊範圍關閉out渠道,因爲渠道不平方關閉。

func sq(in <-chan int) <-chan int { 
    out := make(chan int) 

    go func() { 
    for number := range in { 
     out <- number * number 
    } 
    close(out) 
    }() 

    return out 
} 

調試這種死鎖的一個好方法是發送一個SIGQUIT進程。當接收到SIGQUIT時,運行時轉儲所有goroutine的堆棧。堆棧轉儲通常會指出問題。