2012-09-12 5 views
6

Sto provando a creare un semplice programma per imparare i canali in Go. Ma sto correndo per un errore di stallo, che non riesco a capire"tutte le goroutine sono addormentati - deadlock! Errore di uscita 2" in un programma del ricevitore della stampante

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) 
} 

miei pensieri iniziali era qualcosa circa la funzione di spegnimento, ma anche se Io non comprendo questo ho ancora eseguito in questo messaggio di errore e di uscita. Qualcuno può dare qualche suggerimento su come risolvere questo?

Grazie in anticipo

risposta

8

avete bisogno di due thread di esecuzione perché ora non c'è alcun modo per la funzione reciever per essere chiamato come non si lascia mai la funzione printer. Devi eseguire uno di questi su una goroutine separata.

Si dovrebbe anche close il canale e utilizzare l'operatore range nel proprio ciclo, in modo che termini quando il canale è chiuso.

Quindi vi propongo questo codice:

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

Grazie. L'ho modificato in base ai tuoi suggerimenti e tutti i numeri da 0 a 9 stampe, ma dopo ho ricevuto lo stesso errore. Ho anche aggiunto: \t var stringa di input fmt.Scanln (& input) ma ottengo lo stesso errore dopo che i numeri sono stati stampati. Qualche idea su cosa sto facendo male? – miner

+0

Ho aggiunto il "ricevitore" oltre a rendere la stampante una routine di go, quindi stampa 0-9 senza errori. – miner

+0

Ho modificato in modo preciso come chiudere il canale e terminare la ricezione quando il canale è chiuso. Sembra più pulito (e più riutilizzabile). –

Problemi correlati