与频道和goroutines同步

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
", 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
", 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
", threads)
        for ; threads > 0; threads-- {
                fmt.Println("wait for thread")
                ok := <-waiters
                fmt.Printf("received thread end: %b
", 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!

Simple answer: You need to close queue.

The dual receive operator will only return false iff the channel is closed, which you never do. So the loop in process never exits. Incidentally you can replace your for/if/break with a for/range over a channel.

There are a few other Go idioms that you should consider: have you read http://golang.org/doc/effective_go.html ?