Почему валится простой код на Go?

Начал изучать язык, решил небольшую тестовую прожку написать дабы прочувствовать функционал горутин. Вот код:
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)
}


Валится при запуске:
fatal error: all goroutines are asleep - deadlock!

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


Нагуглил причину - не закрыл channel, но вроде как close() вызываю. И почему дедлок? Единственная причина, которую я вижу, это не синхронизированный доступ к channel из всех моих горутин на чтение, но вроде как я эту конструкцию из мануала официального срисовал, добавив использование sync. Я правильно делаю, или такой пул следует реализовать как-то по другому?
  • Вопрос задан
  • 5951 просмотр
Решения вопроса 1
Очевидно же, канал не буферизирован, main блокируется уже на 2й записи в канал.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@neolink
вы создаете не буфиризированный канал и при попытке 2й раз записать в него (яндекс) горутина уходит в слип, так как ждет его освобождения
поэтому рантайм вам и говорит дедлок, тоесть состояния ничего не делания из которого программа не может выйти сама
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы