P
P
Pavel Shvedov2014-12-17 00:49:17
go
Pavel Shvedov, 2014-12-17 00:49:17

Why does simple Go code fail?

I started learning the language, I decided to write a small test run in order to get a feel for the functionality of goroutines. Here is the code:

package main

import (
  "fmt"
  "net/http"
  "sync"
)

type Task struct {
  id     int32
  addr   string
  method string
}

func head(task *Task) {
  resp, err := http.Head(task.addr)
  if err != nil {
    fmt.Println("Error: %s", task.addr)
  }
  if resp.StatusCode == 200 {
    fmt.Println("Success: %s", task.addr)
  }
}

func handle(queue chan *Task, wg *sync.WaitGroup) {
  for task := range queue {
    head(task)
  }
  wg.Done()
}

func process(queue chan *Task) {
  var wg sync.WaitGroup
  for i := 0; i < 5; i++ {
    wg.Add(1)
    go handle(queue, &wg)
  }
  wg.Wait()
}

func main() {
  fmt.Println("Service Started")
  queue := make(chan *Task)
  queue <- &Task{1, "http://google.ru", "HEAD"}
  queue <- &Task{2, "http://yandex.ru", "HEAD"}
  queue <- &Task{3, "http://mail.ru", "HEAD"}
  queue <- &Task{4, "http://habrahabr.ru", "HEAD"}
  queue <- &Task{5, "http://gmail.ru", "HEAD"}
  queue <- &Task{6, "http://toster.ru", "HEAD"}
  queue <- &Task{7, "http://vkontakte.ru", "HEAD"}
  queue <- &Task{8, "http://facebook.com", "HEAD"}
  queue <- &Task{9, "http://localhost", "HEAD"}
  process(queue)
  close(queue)
}

Crashes on startup:
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]:
main.main()
        C:/Gopath/mobmon_service.git/main.go:60 +0x180

I googled the reason - I did not close the channel, but I seem to call close (). And why deadlock? The only reason I see is not synchronized access to channel from all my reading goroutines, but it seems like I copied this construction from the official manual by adding the use of sync. Am I doing it right, or should such a pool be implemented somehow differently?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
V
Vitaly Yakovenko, 2014-12-17
@mmmaaak

Obviously, the channel is not buffered, main is blocked already on the 2nd entry into the channel.

N
neolink, 2014-12-17
@neolink

you create an unbuffered channel and when you try to write to it (Yandex) for the 2nd time, the goroutine goes into sleep, as it is waiting for it to be released,
so the runtime tells you deadlock, that is, the state of doing nothing from which the program cannot exit itself

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question