面试题答案
一键面试设计思路
- 使用
context.Context
来传递取消信号。context.Context
是Go语言中用于控制多个goroutine生命周期的重要工具。 - 在主程序中创建一个带有取消功能的
context.Context
,并将其传递给每个协程。 - 每个协程在执行任务时,定期检查
context.Context
的取消信号,一旦接收到取消信号,立即停止任务执行并进行必要的资源清理。 - 使用
WaitGroup
来等待所有协程完成任务后再退出主程序。
关键代码片段
package main
import (
"context"
"fmt"
"sync"
"time"
)
func worker(ctx context.Context, wg *sync.WaitGroup, id int) {
defer wg.Done()
for {
select {
case <-ctx.Done():
fmt.Printf("Worker %d received cancel signal, exiting...\n", id)
return
default:
// 模拟耗时任务
fmt.Printf("Worker %d is working...\n", id)
time.Sleep(time.Second)
}
}
}
func main() {
var wg sync.WaitGroup
ctx, cancel := context.WithCancel(context.Background())
// 启动10个协程
for i := 0; i < 10; i++ {
wg.Add(1)
go worker(ctx, &wg, i)
}
// 模拟一段时间后发出退出信号
time.Sleep(5 * time.Second)
cancel()
// 等待所有协程退出
wg.Wait()
fmt.Println("All workers have exited, main program exiting.")
}
在上述代码中:
worker
函数接收context.Context
和WaitGroup
,在循环中通过select
语句监听ctx.Done()
通道,当接收到取消信号时退出循环。main
函数创建了带有取消功能的context.Context
,启动10个协程,并在一段时间后调用cancel()
函数发出取消信号,最后通过wg.Wait()
等待所有协程完成。