面试题答案
一键面试package main
import (
"context"
"fmt"
"time"
)
func longRunningTask(ctx context.Context, ch chan int) {
defer close(ch)
for i := 0; ; i++ {
select {
case <-ctx.Done():
// 清理资源,例如关闭文件、数据库连接等
fmt.Println("任务被取消,清理资源")
return
default:
// 模拟长时间运行的计算
time.Sleep(100 * time.Millisecond)
ch <- i
}
}
}
func main() {
ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
defer cancel()
ch := make(chan int)
go longRunningTask(ctx, ch)
for result := range ch {
fmt.Println("收到结果:", result)
}
fmt.Println("任务结束")
}
在上述代码中:
longRunningTask
函数接受一个context.Context
和一个chan int
。在函数内部使用select
语句监听ctx.Done()
信号,当ctx
被取消时,ctx.Done()
通道会接收到数据,从而可以停止计算并清理资源。- 在
main
函数中,使用context.WithTimeout
创建一个带有超时的context
,并启动longRunningTask
协程。for... range
循环从ch
通道中接收数据,当ch
通道关闭时(longRunningTask
函数结束),循环结束。同时,通过cancel
函数可以手动取消ctx
,在这个例子中是由超时自动触发取消。