我有以下代碼package mainimport ( "fmt" "math/rand" "time")func main() { concurrent := 12 ch := make(chan int) defer close(ch) for i := 1; i <= concurrent; i++ { go worker(i, ch) } for i := 1; i <= 21; i++ { ch <- i }}func worker(worker int, ch chan int) { for requestId := range ch { fmt.Printf("worker %d is requesting to %d...\n", worker, requestId) time.Sleep(time.Duration(rand.Intn(3)) * time.Second) }}該函數啟動運行該函數的多個 goroutine,然后將一些值放入通道中,這些值由 worker 打印。我的問題是,有時通道中的最后一個值甚至更多值不是由工作人員打印的。mainworkerworker 10 is requesting to 10...worker 5 is requesting to 1...worker 5 is requesting to 13...worker 7 is requesting to 6...worker 2 is requesting to 2...worker 3 is requesting to 7...worker 3 is requesting to 14...worker 6 is requesting to 4...worker 11 is requesting to 9...worker 9 is requesting to 8...worker 9 is requesting to 15...worker 12 is requesting to 11...worker 8 is requesting to 12...worker 8 is requesting to 16...worker 4 is requesting to 5...worker 1 is requesting to 3...worker 11 is requesting to 17...我認為這是因為主要功能在打印最后一個值之前結束并“殺死”所有運行goroutine,因為最后所有值都始終被打印出來。func main() { concurrent := 12 ch := make(chan int) defer close(ch) for i := 1; i <= concurrent; i++ { go worker(i, ch) } for i := 1; i <= 21; i++ { ch <- i } time.Sleep(3 * time.Second)}如何在不使用睡眠的情況下解決此問題,并且如果可能的話僅使用通道?
1 回答

RISEBY
TA貢獻1856條經驗 獲得超5個贊
因為主 goroutine 在最后一個循環之后立即退出,導致整個程序也退出,所以后臺 goroutines 可能會也可能不會有機會運行,你必須提供一些同步方法來“等待”所有工作線程完成。for
用sync.WaitGroup
func main() {
concurrent := 12
ch := make(chan int)
var wg sync.WaitGroup
for i := 1; i <= concurrent; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
worker(i, ch)
}(i) // You have to pass i as parameter
}
for i := 1; i <= 21; i++ {
ch <- i
}
close(ch) // Close channel to tell all workers to stop
wg.Wait() // Wait all workers to finish its work
}
- 1 回答
- 0 關注
- 94 瀏覽
添加回答
舉報
0/150
提交
取消