Подтвердить что ты не робот

Почему fmt.Println внутри goroutine не печатает строку?

У меня есть следующий код:

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

}

Если у меня нет кода, который читается из буфера в goroutine, он выводит такое сообщение, которое я ожидаю:

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

Однако, если он внутри goroutine ничего не печатает.

Может кто-нибудь объяснить, почему это?

4b9b3361

Ответ 1

Ваша программа выйдет, когда закончится функция main(). Вероятно, это произойдет до того, как ваш goroutine успеет запустить и распечатать свой результат.

Один из вариантов заключается в том, чтобы чтение основного блока goroutine с канала, и чтобы goroutine записывался на канал, когда он завершил свою работу.

Ответ 2

Другим распространенным способом, который вы увидите в ожидании завершения goroutines, является http://golang.org/pkg/sync/#WaitGroup. вы можете waitGroup.Add(1) для каждого запуска goroutine, затем waitGroup.Done() в goroutine после его завершения, а main может waitGroup.Wait(), и он будет блокироваться до тех пор, пока waitGroup.Done() не будет вызван для каждого Add.

Ответ 3

Запись данных в канал ch в конце goroutine и чтение данных из ch из goroutine может сделать основную функцию ожидающей сообщения goroutine print.

Вот пример:

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
}

Ответ 4

Как указано выше, функция main() будет завершена до того, как у goroutine появится шанс запустить. Горутины как легкие потоки работают в свое время. С целью отладки трюка, который я обычно использую, нужно добавить сон сразу после моего goroutine, достаточно долго, чтобы он позволил моему goroutine закончить. Вот очень простой пример:

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

Ответ 5

Вам нужно добавить задержку времени, например time.Sleep(3 * time.Second) (это ждет 3 секунды).

Горотин закрывается, когда программа завершается. У меня была такая же проблема.