2015-02-19 24 views
5

sto provando con canali Go e confusi con sotto esempio funzione dal blog Go:Restituzione Canali Golang

func gen(nums []int) <-chan int { 
out := make(chan int) 
go func() { 
    for _, n := range nums { 
     out <- n 
    } 
    close(out) 
}() 
fmt.Println("return statement is called ") 
return out 
} 

principale:

func main() { 
c := make(<-chan int) 
c = gen([]int{2, 3, 4, 5}) 

// Consume the output.//Print 2,3,4,5 
fmt.Println(<-c) 
fmt.Println(<-c) 
fmt.Println(<-c) 
fmt.Println(<-c) 
} 

codice completo: http://play.golang.org/p/Qh30wzo4m0

miei dubbi: 1. La mia comprensione è stata, una volta che il ritorno è stato chiamato, la funzione sarà terminata e il canale all'interno di quella funzione non ha più vita. La dichiarazione di ritorno è chiamata solo una volta.Ma il contenuto del canale Out è stato preso più volte. In questo caso, qual è il flusso effettivo di esecuzione? Sono nuovo di Concurrent programming.Kindly aiutare

risposta

4
out := make(chan int) 

Questo non è un canale tamponata, che significa che il out <- n sarà blocco fino a quando qualcuno si legge da qualche parte che i canali (fmt.Println(<-c) chiamate)
(vedi anche " do golang channels maintain order ")

Così il ritorno alla fine della funzione gen() non significa che il letterale go func() è terminato (dal momento che è ancora in attesa per i lettori di consumare il contenuto del canale out).

Ma main funzione ricevendo out canale come ritorno dalla gen() funzione.
Come è possibile ottenerlo dopo che gen() è terminato?

Il fatto che gen() termina non ha alcun effetto sul suo valore restituito (il canale out): l'obiettivo di "gen()" è quello di "creare", che out canale.

main può usare out (come valore restituito di gen()) tempo dopo gen() termina.

Il numero letterale go func all'interno di gen() viene ancora eseguito, anche se gen() viene terminato.

+0

, Grazie per reply.I rapido ottenuto il vostro punto, ma il canale è passato alla funzione principale che attraversa il valore di ritorno del Gen() function.So quando gen() è terminato Come è possibile? –

+1

gen può essere terminato, ma la sua funzione di lettura letterale interna rimane, come una goroutine indipendente. – VonC

+0

variabile 'c' nella principale è il ritorno di gen() function.So quello che stai dicendo è, verrà popolata con valori anche dopo gen() terminato a causa di vivere andare di routine all'interno gen() ... –

1

Perché gen() si spegne la funzione di popolazione del canale come una goroutine;

go func() { 
    for _, n := range nums { 
     out <- n 
    } 
    close(out) 
}() 

e blocca quando il primo valore viene inviato sul canale out, perché non riceve ancora (canali senza buffer blocco sull'invio finché qualcosa riceve su di loro), che goroutine non termina quando la funzione gen() restituisce.

Il riceve da c in main()

fmt.Println(<-c) 
... 

quindi costringere il goroutine iniziato nel gen() per mantenere popolano il canale come i risultati vengono letti, e poi finalmente main() ritorni quando gli torna goroutine, perché non c'è nulla lasciato per inviare su out e niente lasciato per ricevere su c.

Inoltre, lo non è necessario in gen() poiché crea un canale e lo restituisce.

Vedi Playground

+0

@Internet Sono chiaro sul tuo punto: "goroutine non termina quando la funzione gen() restituisce". Ma la funzione principale sta uscendo canale come ritorno dalla funzione gen() .Come è possibile ottenerlo dopo gen() è terminato? Questo è il mio dubbio ... scusa se sto facendo domande stupide, sono nuovo per questo ... –

+0

@faisalkk la funzione 'gen()' restituisce il canale, quindi termina. Il canale non è "posseduto" da quella funzione, è appena creato e restituito (per esempio, la goroutine può essere vista come una funzione separata di "sfondo", che è "rinnegata" dall'uso della parola chiave "go"). . A quel punto la funzione 'gen()' è terminata e il canale può essere utilizzato da altre funzioni. – Intermernet