面试题答案
一键面试- 引入必要的包:
package main import ( "fmt" "sync" )
- 定义全局变量:
var ( taskProgress int mu sync.Mutex )
taskProgress
用于记录全局任务进度。mu
是一个互斥锁,用于避免竞态条件,保护对taskProgress
的访问。
- 子任务函数:
func subTask(wg *sync.WaitGroup) { defer wg.Done() // 模拟子任务执行 // 这里省略具体的业务逻辑 mu.Lock() taskProgress++ mu.Unlock() }
- 子任务函数接受一个
WaitGroup
指针。 - 使用
defer wg.Done()
来标记子任务完成。 - 在更新
taskProgress
之前,先获取互斥锁mu
,更新完成后释放互斥锁,以此避免竞态条件。
- 子任务函数接受一个
- 主函数:
func main() { var wg sync.WaitGroup numSubTasks := 10 for i := 0; i < numSubTasks; i++ { wg.Add(1) go subTask(&wg) } wg.Wait() fmt.Printf("All sub - tasks completed. Total progress: %d\n", taskProgress) }
- 在
main
函数中,初始化一个WaitGroup
。 - 循环创建多个子任务,并为每个子任务调用
wg.Add(1)
来增加等待组的计数。 - 使用
go
关键字启动子任务协程。 - 最后调用
wg.Wait()
等待所有子任务完成,然后输出全局任务进度。
- 在
总结来说,通过 WaitGroup
来同步多个并发子任务的执行,确保所有子任务完成后再进行后续操作,通过 Mutex
来保护对全局任务进度变量 taskProgress
的并发访问,避免竞态条件。