Golang中Waitgroup计数器的执行顺序问题
Golang中Waitgroup计数器的执行顺序问题 我第一次使用等待组。我运行了代码,但代码执行的顺序与我的预期相反。 预期结果: Hello, playground Counter: 0 Counter: 1
请帮助我。
https://play.golang.org/p/U4TDVTbDzN4
感谢您的帮助。 真的非常感谢。
更多关于Golang中Waitgroup计数器的执行顺序问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
你的预期是错误的。goroutine 调度器并非确定性的。
package main
import (
"fmt"
"sync"
)
var wg sync.WaitGroup
func printer(counter int) {
fmt.Println("Counter:\t", counter)
wg.Done()
}
func main() {
counter := 0
for i := 0; i < 10; i++ {
wg.Add(1)
go printer(counter)
counter++
}
wg.Wait()
}
https://play.golang.org/p/wMs_I-7MRxN。
. 运行 1: Counter: 9 Counter: 0 Counter: 1 Counter: 2 Counter: 3 Counter: 4 Counter: 5 Counter: 7 Counter: 6 Counter: 8 . 运行 2: Counter: 9 Counter: 0 Counter: 1 Counter: 5 Counter: 2 Counter: 3 Counter: 4 Counter: 7 Counter: 6 Counter: 8 . 运行 3: Counter: 9 Counter: 3 Counter: 0 Counter: 1 Counter: 2 Counter: 6 Counter: 4 Counter: 5 Counter: 7 Counter: 8 .
在Go语言中,sync.WaitGroup 的计数器操作顺序确实会影响并发执行的结果。根据你提供的代码链接,问题在于 wg.Add(1) 和 wg.Done() 的调用时机。
以下是修正后的代码示例:
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
for i := 0; i < 2; i++ {
wg.Add(1) // 在启动goroutine前增加计数器
go func(x int) {
defer wg.Done() // 使用defer确保计数器减少
fmt.Printf("Counter:\t %d\n", x)
}(i)
}
fmt.Println("Hello, playground")
wg.Wait() // 等待所有goroutine完成
}
关键点:
wg.Add(1)必须在每个goroutine启动前调用- 使用
defer wg.Done()确保goroutine结束时减少计数器 wg.Wait()会阻塞直到计数器归零
执行顺序:
- 主goroutine先打印 “Hello, playground”
- 两个goroutine并发执行,输出顺序可能为 0,1 或 1,0
wg.Wait()确保所有goroutine完成后再退出程序
如果你需要严格的顺序输出,需要使用同步机制如通道或互斥锁,而不是WaitGroup。

