2015-11-08 128 views
3

下面這段代碼爲什麼會產生錯誤?這段代碼爲什麼會產生一個錯誤?

func main() { 

    messages := make(chan string) 

    messages <- "test" //line 16 

    fmt.Println(<-messages) 

} 

生成以下錯誤。

fatal error: all goroutines are asleep - deadlock! 
goroutine 1 [chan send]: 
main.main() 
    /tmp/sandbox994400718/main.go:16 +0x80 

將值發送到通道,並在下一行中接收值。技術上它應該工作。

回答

0

我現在已經學到了很多渠道,現在我可以回答這個問題。

在管線16時消息「測試」是由主螺紋(夠程)的執行暫停和運行時查找,其已準備好從信道信息接收值其他夠程發送到信道。由於沒有其他通道,運行時會引發死鎖消息的恐慌。這是一個死鎖的經典例子。

要解決這個問題有可以做兩件事情。

1)使用緩衝通道馬特建議的答案(之一)。

2)否則具有發送到信道或信道從在一去例程接收的發言。

func main() { 

    messages := make(chan string) 

    go func() { 
     messages <- "test" //line 16 
    }() 
    fmt.Println(<-messages) 

} 

所以從這個基本拿走的題是,

1)通道只能用來夠程即之間的通信,當你發送一個夠程信道只能在其他的goroutine收到它不一樣。

2)當數據以的goroutine直到該數據被從在另一個的goroutine相同的信道接收到的goroutine的流量/執行暫停發送給信道。

4

通道可以是緩衝無緩衝。一個緩衝通道可以在內部存儲多個項目,但是當你向緩衝通道添加一些項目時,添加項目的goroutine只能在另一個goroutine刪除項目時繼續。沒有地方「離開」物品,它必須直接傳遞給另一個goroutine,並且第一個goroutine將等到另一個人從其中取出物品。

這就是你的代碼中發生的事情。當您使用make創建頻道時,如果您未指定容量作爲第二個參數,則會獲得無緩衝的頻道。要創建緩衝通道,請將第二個參數傳遞給make,e.g

messages := make(chan string, 1) // could be larger than 1 if you want 

這使得夠程的項目(在這種情況下string)添加到頻道,在那裏將可在另一夠程試圖在未來的渠道得到一個項目,原來的夠程然後可以繼續處理。

+0

我得到的,但怎麼就是這個例子http://play.golang.org/p/2ox5ObgKIP不需要緩衝。 – nJoshi

+3

@nJoshi在那個例子中有_two_ goroutines。 goroutine以'go func()...'開始,將字符串傳遞給通道(並等待),主要goroutine檢索它(並允許另一個繼續)。 – matt

相關問題