I'm trying to implement a "workers" system, but I'm having some issues identifying why it deadlocks itself
The code is executed by calling fillQueue()
I do not understand why my code ends up in a dealock (on process is waiting in the second line of "process()", reading from the channel "queue", while the other is waiting at the end of "fillQueue()" waiting to read from waiters.
I do not understand why it never gets the read on waiters.
func process(queue chan *entry, waiters chan bool) {
for {
entry, ok := <-queue
if ok == false {
break
}
fmt.Println("worker: " + entry.name)
entry.name = "whatever"
}
fmt.Println("worker finished")
waiters <- true
}
func fillQueue(q *myQueue) {
// fill our queue
queue := make(chan *entry, len(q.pool))
for _, entry := range q.pool {
fmt.Println("push entry")
queue <- entry
}
fmt.Printf("entry cap: %d\n", cap(queue))
// start the readers
var total_threads int
if q.maxConcurrent <= len(q.pool) {
total_threads = q.maxConcurrent
} else {
total_threads = len(q.pool)
}
waiters := make(chan bool, total_threads)
fmt.Printf("waiters cap: %d\n", cap(waiters))
var threads int
for threads = 0; threads < total_threads; threads++ {
fmt.Println("start worker")
go process(queue, waiters)
}
fmt.Printf("threads started: %d\n", threads)
for ; threads > 0; threads-- {
fmt.Println("wait for thread")
ok := <-waiters
fmt.Printf("received thread end: %b\n", ok)
}
}
Here is the log when I run it:
push entry
push entry
push entry
entry cap: 3
waiters cap: 1
start worker
threads started: 1
wait for thread
worker: name1
worker: name2
worker: name3
throw: all goroutines are asleep - deadlock!