[英]Testing go channel throughput - all goroutines deadlock
我做了一個小程序來測試通道吞吐量,但它總是死鎖,我努力但卻無法理解為什么:
package main
import (
"fmt"
"runtime"
)
const CONCURRENCY = 32
const WORK_PER_WORKER = 100
const TOTAL_WORK = CONCURRENCY * WORK_PER_WORKER
func 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
}
}
你的代碼go func(i int) { anItem := <-workQueue[i]; ... }
go func(i int) { anItem := <-workQueue[i]; ... }
從workQueue[i]
刪除workQueue[i]
1項,但是您正在嘗試將WORK_PER_WORKER項填充到其中。 您將處理CONCURRENCY許多項目,然后所有讀取goroutines已終止並且您遇到了僵局。
循環工作者goroutines“解決”你的僵局: http : //play.golang.org/p/j2pavqnBDv只是“解決”因為這些工作者goroutines永遠不會終止。 也許您可以嘗試close
您的頻道,以便在沒有任何內容發送時通知工作人員goroutines。
因為您的工作人員只處理一個任務然后退出。 因此,只有第一個CONCURRENCY
項目繼續進行,然后workQueue[i/WORK_PER_WORKER] <- workToDo
阻塞。 因此, completed
陳永遠不會收到足夠的值, main
也永遠阻止。
你的工作者應該在循環中工作,如下所示:
for i := 0; i < CONCURRENCY; i++ {
go func(i int) {
for anItem := range workQueue[i] {
work()
anItem.Done <- 1
}
}(i)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.