2012-09-12 8 views
6

Estoy tratando de crear un programa simple para aprender canales en Go. Pero estoy corriendo en un error de punto muerto, lo que no puedo entender por"todos los goroutines están dormidos - interbloqueo! Exit estado 2" error en un programa receptor de impresora

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

Mis pensamientos iniciales fue algo acerca de la función del sueño, pero incluso si No te incluyo este todavía se encuentra con este error y mensaje de salida. ¿Alguien puede dar algunos consejos sobre cómo resolver esto?

Gracias de antemano

Respuesta

8

Se necesitan dos hilos de ejecución porque ahora no hay forma para la función reciever a ser llamado como nunca dejar la función printer. Necesitas ejecutar uno de ellos en un goroutine separado.

También debe close el canal y usar el operador range en su bucle, para que finalice cuando el canal esté cerrado.

Así que le propone este código:

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

Gracias. Lo modifiqué de acuerdo con sus consejos, y todos los números del 0 al 9 imprime, pero luego aparece el mismo error después de eso. También agregué: \t cadena de entrada de var fmt.Scanln (y entrada) pero obtengo el mismo error después de que se imprimen los números. ¿Alguna idea de lo que estoy haciendo mal? – miner

+0

Agregué 'go reciever' además de convertir la impresora en una rutina, y luego imprime 0 - 9 sin errores. – miner

+0

He editado para precisar cómo debe cerrar el canal y finalizar la recepción cuando el canal está cerrado. Parece más limpio (y más reutilizable). –

Cuestiones relacionadas