2012-09-13 12 views
19

Dado el siguiente programa sencillo Irtiro: todos goroutines están dormidos - callejón sin salida

package main 

import (
    "fmt" 
) 

func total(ch chan int) { 
    res := 0 
    for iter := range ch { 
     res += iter 
    } 
    ch <- res 
} 

func main() { 
    ch := make(chan int) 
    go total(ch) 
    ch <- 1 
    ch <- 2 
    ch <- 3 
    fmt.Println("Total is ", <-ch) 
} 

Me pregunto si alguien me puede aclarar por qué tengo

throw: all goroutines are asleep - deadlock! 

gracias

Respuesta

30

Como nunca cierra el canal ch, el bucle de rango nunca terminará.

No puede devolver el resultado en el mismo canal. Una solución es usar una diferente.

Su programa podría adaptarse de esta manera:

package main 

import (
    "fmt" 
) 

func total(in chan int, out chan int) { 
    res := 0 
    for iter := range in { 
     res += iter 
    } 
    out <- res // sends back the result 
} 

func main() { 
    ch := make(chan int) 
    rch := make(chan int) 
    go total(ch, rch) 
    ch <- 1 
    ch <- 2 
    ch <- 3 
    close (ch) // this will end the loop in the total function 
    result := <- rch // waits for total to give the result 
    fmt.Println("Total is ", result) 
} 
+1

No directamente relacionada con la pregunta, pero sigue siendo interesante para la comprensión de goroutines: si se agrega 'fmt.Println ("Salida Total")' 'después de salir <- res' que nunca puede ver que, como el programa puede salir antes, sin esperar a que los goroutines se completen. –

+0

Comencé a aprender Go hace unos días y no puedo entender cómo se resuelve: = 0 se está ejecutando solo una vez? ¿No se supone que la función completa se ejecuta 3 veces? Solo el ciclo se ejecuta 3 veces en su ejemplo. – if237912print

+0

@OybekToirov Toda la función se ejecuta solo una vez, la iteración progresa cada vez que hay algo en el canal int 'en' –

-3

Esto también es correcto.

package main 

import "fmt" 

func main() { 
    c := make(chan int) 
    go do(c) 
    c <- 1 
    c <- 2 
    // close(c) 
    fmt.Println("Total is ", <-c) 
} 

func do(c chan int) { 
    res := 0 
    // for v := range c { 
    // res = res + v 
    // } 
    for i := 0; i < 2; i++ { 
     res += <-c 
    } 
    c <- res 
    fmt.Println("something") 
} 
+3

Esto no responde la pregunta de qué estaba mal con el programa original. –

Cuestiones relacionadas