面试题答案
一键面试sync.WaitGroup工作原理
- 计数器:
sync.WaitGroup
内部维护一个计数器,用于记录需要等待完成的任务数量。这个计数器是一个无符号整数,它初始值为0。
- Add方法:
Add
方法用于增加计数器的值。通常在启动新的协程前调用Add
方法,将计数器增加相应的数量,表明后续会有这么多协程需要等待完成。例如,如果要启动5个协程,就可以调用Add(5)
。- 如果
Add
方法传入的参数是负数,会导致运行时恐慌(panic)。
- Done方法:
Done
方法是Add(-1)
的便捷写法。每个协程在完成其任务后,调用Done
方法,将计数器的值减1。这表示该协程已经完成了任务,等待组可以少等待一个任务。
- Wait方法:
Wait
方法会阻塞调用它的协程,直到计数器的值变为0。当所有需要等待的协程都调用了Done
方法,计数器减为0,Wait
方法才会返回,阻塞的协程得以继续执行。
协作逻辑示例
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
wg.Add(3) // 启动3个协程,所以计数器设为3
go func() {
defer wg.Done() // 协程结束时,计数器减1
fmt.Println("协程1完成任务")
}()
go func() {
defer wg.Done()
fmt.Println("协程2完成任务")
}()
go func() {
defer wg.Done()
fmt.Println("协程3完成任务")
}()
wg.Wait() // 主线程阻塞,直到计数器为0
fmt.Println("所有协程已完成任务")
}
在上述代码中,主线程调用wg.Add(3)
增加计数器,3个协程在完成任务后调用wg.Done()
减少计数器,主线程通过wg.Wait()
等待计数器归零,确保所有协程完成任务后再继续执行后续代码。