面试题答案
一键面试思路
- 利用
context.Context
的取消功能:context.Context
本身具有取消功能,我们可以在一个子协程完成任务时,调用取消函数来通知其他子协程。 - 在子协程中监听取消信号:每个子协程在执行任务的过程中,需要不断检查
context.Context
是否被取消。一旦检测到取消信号,就停止当前的工作,并清理相关资源。
关键代码片段(以Go语言为例)
package main
import (
"context"
"fmt"
"time"
)
func worker(ctx context.Context, id int) {
for {
select {
case <-ctx.Done():
fmt.Printf("Worker %d received cancel signal, stopping...\n", id)
return
default:
// 模拟工作
fmt.Printf("Worker %d is working...\n", id)
time.Sleep(100 * time.Millisecond)
}
}
}
func main() {
// 创建带有超时的context
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
defer cancel()
// 启动多个子协程
for i := 1; i <= 3; i++ {
go worker(ctx, i)
}
// 模拟某个子协程提前完成任务
go func() {
time.Sleep(200 * time.Millisecond)
fmt.Println("One worker finished, canceling others...")
cancel()
}()
// 等待一段时间,确保所有子协程有机会处理取消信号
time.Sleep(300 * time.Millisecond)
}
在上述代码中:
worker
函数代表子协程,通过select
语句监听ctx.Done()
通道来检测是否收到取消信号。- 在
main
函数中,首先创建了一个带有超时的context
,然后启动多个worker
子协程。 - 模拟某个子协程提前完成任务,调用
cancel
函数,这会向所有子协程的ctx.Done()
通道发送信号,从而通知它们停止工作。同时,原有的超时机制依然生效,如果在超时时间内没有手动调用cancel
,context
也会自动取消。