2013-04-26 8 views
42

Ho il seguente codice:Perché fmt.Println all'interno di una goroutine non stampa una riga?

package main 

import "net" 
import "fmt" 
import "bufio" 

func main() { 
    conn, _ := net.Dial("tcp", "irc.freenode.net:6667") 

    reader := bufio.NewReader(conn) 
    go func() { 
     str, err := reader.ReadString('\n') 
     if err != nil { 
      // handle it 
      fmt.Println(err) 
     } 
     fmt.Println(str) 
    }() 

} 

Se non ho il codice che legge dal buffer in un goroutine, esso emette un messaggio come questo, che è quello che mi aspetto che accada:

:zelazny.freenode.net NOTICE * :*** Looking up your hostname... 

Tuttavia, averlo in una goroutine non stampa nulla.

Qualcuno può spiegare perché lo è?

risposta

50

Il programma uscirà quando termina la funzione main(). Questo è probabile che accada prima che la tua goroutine abbia il tempo di correre e stampare la sua uscita.

Un'opzione potrebbe essere quella di leggere il blocco di goroutine principale da un canale e fare in modo che la goroutine scriva sul canale quando ha completato il suo lavoro.

+1

Grazie per la grande spiegazione, James. Sicuramente penso che i canali siano ciò che sto cercando. –

24

Un altro modo comune che vedrai implementato nell'attesa che le goroutine finiscano è http://golang.org/pkg/sync/#WaitGroup. è possibile waitGroup.Add(1) per ogni goroutine avviata, quindi waitGroup.Done() nella goroutine dopo aver terminato, e la cassetta principale waitGroup.Wait() e si bloccherà fino al waitGroup.Done() è stato chiamato per ogni Aggiungi.

+0

Grazie per aver condiviso, Erik. –

-1

Come detto sopra, la funzione main() si chiuderà prima che la goroutine abbia la possibilità di funzionare. Le goroutine come fili leggeri funzionano nel loro tempo libero. Ai fini del debugging il trucco che uso di solito è aggiungere un sonno subito dopo la mia goroutine, abbastanza a lungo da permettere alla mia goroutine di finire. Ecco un esempio molto semplice:

package main                                     

import (
    "fmt" 
    "time" 
) 

func main() { 
    fmt.Println("Hello gopher!") 
    go print_nums(10) 
    time.Sleep(time.Millisecond * 100) // if i take this line out all i will see is hello and bye gopher! 
    fmt.Println("Bye gopher!") 
} 

func print_nums(num int) { 
    i := 0 
    for i < num { 
    fmt.Println(i) 
    i++ 
    } 
} 
-3

È necessario aggiungere un ritardo del genere time.Sleep(3 * time.Second) (questo attende 3 secondi).

La goroutine si chiude quando il programma termina. Ho avuto lo stesso identico problema.

1

Scrivere dati su un canale ch alla fine della goroutine e leggere i dati da ch fuori goroutine può rendere la funzione principale in attesa di messaggio di stampa goroutine.

Ecco un esempio:

package main 

import "net" 
import "fmt" 
import "bufio" 

func main() { 
conn, _ := net.Dial("tcp", "irc.freenode.net:6667") 

reader := bufio.NewReader(conn) 
ch := make(chan byte, 1) 
go func() { 
    str, err := reader.ReadString('\n') 
    if err != nil { 
     // handle it 
     fmt.Println(err) 
    } 
    fmt.Println(str) 
    ch <- 1 
    }() 
    <-ch 
} 
Problemi correlati