以下是我的代码中的相关摘录:
func main() {
quit := make(chan int)
readyQueue := make(chan Proc)
runQueue := make(chan Proc)
waitQueue := make(chan Proc)
procList := getInitialProcList()
fmt.Println(procList)
for _, proc := range(procList) {
switch {
case proc.Status == READY:
readyQueue <- proc
tick(quit, readyQueue, runQueue, waitQueue)
case proc.Status == RUN:
runQueue <- proc
tick(quit, readyQueue, runQueue, waitQueue)
case proc.Status == WAIT:
waitQueue <- proc
tick(quit, readyQueue, runQueue, waitQueue)
}
}
<-quit // blocks to keep main thread alive
}
func tick(quit chan int, readyQueue chan Proc, runQueue chan Proc, waitQueue chan Proc) {
select {
case p := <-readyQueue:
fmt.Println(p)
default:
fmt.Println("[tick] nothing in ready queue")
}
select {
case p := <-waitQueue:
fmt.Println(p)
default:
fmt.Println("[tick] nothing in wait queue")
}
select {
case p := <-runQueue:
fmt.Println(p)
default:
fmt.Println("[tick] nothing in run queue")
}
quit <- 0
}
我不明白为什么我在上面的代码中的fatal error: all goroutines are asleep - deadlock!
行上收到错误readyQueue <- proc
。
答案 0 :(得分:14)
就代码所示,您永远不会为您创建的任何频道启动并发阅读器。因为它们是无缓冲的,所以对它们的任何写入都将阻塞,直到有人在某处从另一端读取。在您的代码中不是这种情况。
如果tick
应该是消费者,你应该在进入循环之前将其激活。
然后它应该有一个循环本身,所以它不断轮询通道的新值。
go tick(quit, readyQueue, runQueue, waitQueue)
for _, proc := range(procList) {
....
}
另一个直接的解决方案是使用缓冲区1创建所有通道。
quit := make(chan int, 1)
readyQueue := make(chan Proc, 1)
runQueue := make(chan Proc, 1)
waitQueue := make(chan Proc, 1)
虽然这可以解决您的直接问题,但您的设计仍然存在其他一些潜在问题。我们需要确切地知道你想要完成的是什么,以便给出一个更全面的答案。