我有以下代码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 关注
- 102 浏览
添加回答
举报
0/150
提交
取消