以下是一些Go语言中context
包的基本使用代码示例:
示例1:带有取消功能的简单示例
package main
import (
"context"
"fmt"
"time"
)
func main() {
// 创建一个可取消的Context和对应的取消函数
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
// 启动一个goroutine,它会在一个无限循环中监听Context是否被取消
go func() {
for {
select {
case <-ctx.Done():
fmt.Println("接收到取消信号,goroutine退出...")
return
default:
time.Sleep(1 * time.Second)
fmt.Println("仍在执行任务...")
}
}
}()
// 在主goroutine中,等待一段时间后取消Context
time.Sleep(3 * time.Second)
cancel() // 执行取消操作
// 程序在此会继续执行,直到所有goroutine完成
}
示例2:带有超时功能的Context
package main
import (
"context"
"fmt"
"time"
)
func longRunningTask(ctx context.Context) {
for {
select {
case <-ctx.Done():
fmt.Println("任务超时或被取消,退出longRunningTask")
return
default:
fmt.Println("正在进行任务...")
time.Sleep(1 * time.Second)
}
}
}
func main() {
// 创建一个带超时限制的Context
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
go longRunningTask(ctx)
// 主goroutine在这里等待超时发生或取消
<-ctx.Done()
fmt.Println("主线程:", ctx.Err()) // 输出超时错误信息
}
示例3:传递值的Context
package main
import (
"context"
"fmt"
)
type userKey struct{}
func main() {
// 创建一个基础Context
baseCtx := context.Background()
// 添加一个值到Context中
userID := "123"
valueCtx := context.WithValue(baseCtx, userKey{}, userID)
// 在接收方提取值
if val, ok := valueCtx.Value(userKey{}).(string); ok {
fmt.Printf("提取到的用户ID是:%s\n", val)
} else {
fmt.Println("未能成功提取用户ID")
}
}
以上示例分别展示了如何创建并使用可取消的Context、带超时限制的Context,以及如何通过WithValue
方法在Context中传递自定义值。