面试题答案
一键面试在Go语言中,context
包用于管理goroutine
的生命周期,以下为具体操作及示例:
创建context
-
创建背景context
context.Background()
用于创建一个空的上下文,通常作为所有上下文的根。context.TODO()
用于当不确定使用何种上下文时的占位符。
-
创建可取消的context
context.WithCancel(parent context.Context)
:创建一个可取消的上下文,返回一个新的上下文和取消函数。当调用取消函数时,新的上下文会收到取消信号。context.WithDeadline(parent context.Context, deadline time.Time)
:创建一个带有截止时间的上下文,到截止时间时,上下文会自动取消。context.WithTimeout(parent context.Context, timeout time.Duration)
:创建一个带有超时时间的上下文,经过指定的超时时间后,上下文会自动取消。
传递context
- 通过函数参数传递:在调用
goroutine
的函数中,将context
作为参数传递进去。这样可以确保所有相关的goroutine
共享相同的上下文,从而实现统一的生命周期管理。
在goroutine中根据context信号操作
- 监听取消信号:在
goroutine
内部,使用select
语句监听context.Done()
通道。当该通道接收到数据时,意味着上下文被取消,goroutine
应该进行清理工作并退出。
示例代码
package main
import (
"context"
"fmt"
"time"
)
func worker(ctx context.Context) {
for {
select {
case <-ctx.Done():
fmt.Println("收到取消信号,退出goroutine")
return
default:
fmt.Println("工作中...")
time.Sleep(1 * time.Second)
}
}
}
func main() {
// 创建可取消的context
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel() // 确保在函数结束时取消,防止资源泄漏
// 启动goroutine
go worker(ctx)
// 主goroutine等待一段时间,模拟其他工作
time.Sleep(5 * time.Second)
fmt.Println("主goroutine结束")
}
在上述示例中,首先创建了一个带有3秒超时的上下文ctx
和取消函数cancel
。worker
函数在goroutine
中运行,通过select
监听ctx.Done()
通道。当超时时间到或者手动调用cancel
函数时,ctx.Done()
通道会收到数据,worker
函数收到取消信号后清理并退出。