我做了一个小程序来对 go channel 吞吐量进行基准测试,但是它总是死锁,我很努力地尝试但不明白为什么:package mainimport ( "fmt" "runtime")const CONCURRENCY = 32const WORK_PER_WORKER = 100const TOTAL_WORK = CONCURRENCY * WORK_PER_WORKERfunc work() { sum := 0 for i := 0; i < 10000000; i++ { sum *= i }}type WorkItem struct { Done chan int}func main() { runtime.GOMAXPROCS(CONCURRENCY) var workQueue [CONCURRENCY]chan *WorkItem // initialize workers for i := 0; i < CONCURRENCY; i++ { workQueue[i] = make(chan *WorkItem) } // start workers for i := 0; i < CONCURRENCY; i++ { go func(i int) { anItem := <-workQueue[i] work() anItem.Done <- 1 }(i) } completed := make(chan bool, TOTAL_WORK) for i := 0; i < TOTAL_WORK; i++ { go func(i int) { // send work to queues workToDo := &WorkItem{Done: make(chan int)} workQueue[i/WORK_PER_WORKER] <- workToDo // !! DEADLOCK // wait until the work is done <-workToDo.Done completed <- true }(i) } fmt.Println("Waiting") for i := 0; i < TOTAL_WORK; i++ { <-completed }}
2 回答
隔江千里
TA贡献1906条经验 获得超10个赞
因为你的工人只处理一项任务然后退出。因此,只有第一个CONCURRENCY项目继续进行,然后workQueue[i/WORK_PER_WORKER] <- workToDo无限地阻塞。因此,completedchan 永远不会收到足够的值并且main永远阻塞。
您的工作人员应该在循环中工作,如下所示:
for i := 0; i < CONCURRENCY; i++ {
go func(i int) {
for anItem := range workQueue[i] {
work()
anItem.Done <- 1
}
}(i)
}
- 2 回答
- 0 关注
- 260 浏览
添加回答
举报
0/150
提交
取消