2012-09-12 19 views
6

我正在嘗試創建一個簡單程序來學習Go中的通道。 但死鎖錯誤,這我不能想出打印機 - 接收程序中的「所有程序都睡着了 - 死鎖!退出狀態2」錯誤

package main 

import (
    "fmt" 
    "time" 
) 

func printer(c chan int) { 
    for i := 0; i < 10; i++ { 
     c <- i 
     time.Sleep(time.Second) 
    } 
} 

func reciever(c chan int) { 
    for { 
     recievedMsg := <-c 
     fmt.Println(recievedMsg) 
    } 
} 

func main() { 
    newChanel := make(chan int) 
    printer(newChanel) 
    reciever(newChanel) 
} 

我最初的想法運行I'm是一些有關睡眠功能,但即使我不包括這個,我仍然會碰到這個錯誤和退出消息。 任何人都可以提供一些關於如何解決這個問題的提示嗎?

在此先感謝

回答

8

需要兩個執行線程因爲現在沒有辦法對被稱爲reciever功能,你永遠不會離開printer功能。您需要在單獨的goroutine上執行其中的一個。

您還應該使用close通道,並在迴路中使用range運算符,以便在通道關閉時結束。

所以我建議你這樣的代碼:

func printer(c chan int) { 
    for i := 0; i < 10; i++ { 
     c <- i 
     time.Sleep(time.Second) 
    } 
    close(c) 
} 

func reciever(c chan int) { 
    for recievedMsg := range c { 
     fmt.Println(recievedMsg) 
    } 
} 

func main() { 
    newChanel := make(chan int) 
    go printer(newChanel) 
    reciever(newChanel) 
} 
+0

感謝。我根據您的提示對其進行了修改,並從0 - 9打印所有數字,但之後出現相同的錯誤。我還補充道:\t var輸入字符串 fmt.Scanln(&input)但打印數字後出現同樣的錯誤。任何想法我做錯了什麼? – miner

+0

除了使打印機成爲例行打印機之外,我還添加了'go reciever',然後打印0 - 9,沒有錯誤。 – miner

+0

我編輯了精確的聲道,當頻道關閉時應如何關閉頻道並結束接收。它看起來更清潔(並且更可重用)。 –