你的代码在并发执行任务时有一个问题。在你定义的任务发送部分,使用了闭包(func(i int)
)但没有将 i
的值传递给它,这会导致所有的 goroutine 都引用同一个 i
,而这个值在循环结束时会是 numTask
。
为了修复这个问题,你需要将当前的循环变量 i
作为参数传递到 goroutine 中。可以通过定义一个新的变量来捕获当前的 i
值。以下是修改后的代码:
package main
import (
"fmt"
"sync"
)
func main() {
numTask := 100
concurrency := 5
var wg sync.WaitGroup
taskCh := make(chan func())
wg.Add(concurrency)
for i := 0; i < concurrency; i++ {
go func() {
defer wg.Done()
for task := range taskCh {
task()
}
}()
}
for i := 0; i < numTask; i++ {
i := i // 捕获当前的 i 值
taskCh <- func() {
fmt.Printf("task %d is running\n", i)
}
}
close(taskCh) // 在发送完所有任务后关闭通道
wg.Wait() // 等待所有 goroutine 完成
}
修改内容:
- 在 for 循环中,通过
i := i
创建一个新的局部变量,从而确保每个闭包都能捕获到正确的i
值。 - 在提交任务后调用
close(taskCh)
来关闭任务通道,以通知所有消费者不再有新任务。 - 最后调用
wg.Wait()
来等待所有 goroutine 完成。
这样修改后,程序应该能够正确地并发执行每个任务,并打印出每个任务的 ID。
内容由零声教学AI助手提供,问题来源于学员提问