Почему валится простой код на 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. Я правильно делаю, или такой пул следует реализовать как-то по другому?
  • Вопрос задан
  • 5657 просмотров
Решения вопроса 1
Очевидно же, канал не буферизирован, main блокируется уже на 2й записи в канал.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@neolink
вы создаете не буфиризированный канал и при попытке 2й раз записать в него (яндекс) горутина уходит в слип, так как ждет его освобождения
поэтому рантайм вам и говорит дедлок, тоесть состояния ничего не делания из которого программа не может выйти сама
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы