В следующем коде я пытаюсь создать MaxOutstanding
количество обработчиков. Каждый обработчик перебирает элементы в очереди queue
и распечатывает их, я также пишу true
на канал done
.goroutine asleep - deadlock
В моей основной функции я запускаю обработчики и записываю 9 элементов в queue
и жду, пока 1-й элемент будет записан в очередь done
.
package main
import "fmt"
type Request struct {
int32
}
var MaxOutstanding = 5
func handle(queue chan *Request, i int, done chan bool) {
for r := range queue {
fmt.Println(i, "---", r)
done <- true
}
}
func Serve(clientRequests chan *Request, quit, done chan bool) {
// Start handlers
for i := 0; i < MaxOutstanding; i++ {
go handle(clientRequests, i, done)
}
<-quit // Wait to be told to exit.
}
func main() {
clientRequests := make(chan *Request)
quit := make(chan bool)
done := make(chan bool)
go Serve(clientRequests, quit, done)
clientRequests <- &Request{4}
clientRequests <- &Request{1}
clientRequests <- &Request{2}
clientRequests <- &Request{3}
clientRequests <- &Request{5}
clientRequests <- &Request{6}
clientRequests <- &Request{7}
clientRequests <- &Request{8}
clientRequests <- &Request{9}
fmt.Println("...........>", <- done)
close(clientRequests)
close(done)
}
При выполнении я получаю следующее сообщение об ошибке. Я не понимаю, что случилось с реализацией, я даже закрываю канал.
4 --- &{4}
0 --- &{1}
1 --- &{2}
2 --- &{3}
3 --- &{5}
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.main()
/home/ubuntu/digs-svc/src/digs/go1.go:45 +0x251
goroutine 5 [chan receive]:
main.Serve(0xc82004c060, 0xc82004c0c0, 0xc82004c120)
/home/ubuntu/digs-svc/src/digs/go1.go:28 +0x92
created by main.main
/home/ubuntu/digs-svc/src/digs/go1.go:37 +0xb9
goroutine 6 [chan send]:
main.handle(0xc82004c060, 0x0, 0xc82004c120)
/home/ubuntu/digs-svc/src/digs/go1.go:16 +0x23b
created by main.Serve
/home/ubuntu/digs-svc/src/digs/go1.go:25 +0x5b
EDIT:
Видимо, fmt.Println("....", <- done)
не было достаточно, чтобы показать, что есть потребитель в done
канале. Я переместил код в порядке выполнения. Потребитель должен «слушать» канал, когда данные записываются на него. В моем предыдущем коде, когда были записаны первые данные, потребителя не было.
Рабочий код.
https://play.golang.org/p/98l2M4XO9t
На первый взгляд вы пишете ' сделал 'не менее 5 раз, но прочитал его только один раз. – myaut
@myaut, Это намерение. Меня интересует только первый экземпляр записываемых данных. – Pratyush