长沙做网站比较好的公司,网站设计网络推广商贸平台,给你一个网站你怎么做,遵义网站制作小程序作用
context字面意思上下文#xff0c;用于关联管理上下文#xff0c;具体有如下几个作用
取消信号传递#xff1a;可以用来传递取消信号#xff0c;让一个正在执行的函数知道它应该提前终止。超时控制#xff1a;可以设定一个超时时间#xff0c;自动取消超过执行时间…
作用
context字面意思上下文用于关联管理上下文具体有如下几个作用
取消信号传递可以用来传递取消信号让一个正在执行的函数知道它应该提前终止。超时控制可以设定一个超时时间自动取消超过执行时间的操作。截止时间与超时类似但是是设定一个绝对时间点而不是时间段。值传递可以安全地在请求的上下文中传递数据避免了使用全局变量或者参数列表不断增长。
由上述看出context有个重要用途控制取消。
场景与用法
示例1HTTP 请求处理
在处理 HTTP 请求时可以为每个请求创建一个 context用于控制请求处理的整个生命周期。如果请求被取消或超时依赖该 context 的操作也会被取消。
代码示例
package mainimport (contextfmtmath/randnet/httptime
)func randomSleepAtMost2s() {rand.Seed(time.Now().UnixNano()) // 初始化随机数种子// 生成 0 到 2000 之间的随机整数毫秒randomMillis : rand.Intn(2000)// 转换为 time.Duration 类型并乘以 time.MillisecondsleepDuration : time.Duration(randomMillis) * time.Millisecond// 随机睡眠fmt.Println(sleeping for, sleepDuration)time.Sleep(sleepDuration)
}func handler(w http.ResponseWriter, r *http.Request) {// 超时时间1sctx, cancel : context.WithTimeout(r.Context(), 1*time.Second)defer cancel()// 创建一个模拟正常处理完成的通道done : make(chan struct{})// 模拟异步处理逻辑go func() {// 模拟耗时操作// - 当随机睡眠超过1s时会触发 ctx.Done()取消请求// - 当随机睡眠不超过1s时则会正常处理请求randomSleepAtMost2s()fmt.Println(request processed)close(done) // 处理完成关闭通道}()// 模拟耗时操作select {case -done:w.WriteHeader(http.StatusOK)w.Write([]byte(request processed successfully))case -ctx.Done():fmt.Println(request cancelled)http.Error(w, request cancelled, http.StatusRequestTimeout)return}
}func main() {http.HandleFunc(/, handler)http.ListenAndServe(:8080, nil)
}
示例2 数据库操作
数据库查询或操作可以接受一个 context 参数允许查询在超时或被取消时立即停止避免无谓的数据库资源占用。
代码示例
package mainimport (contextdatabase/sqlfmttime_ github.com/lib/pq // 假设使用 PostgreSQL
)func queryWithTimeout(ctx context.Context, db *sql.DB, query string) (*sql.Rows, error) {// 设置1s的超时时间ctx, cancel : context.WithTimeout(ctx, 1*time.Second)defer cancel()return db.QueryContext(ctx, query)
}func main() {// 连接数据库示例db, err : sql.Open(postgres, your_connection_string)if err ! nil {panic(err)}defer db.Close()ctx : context.Background()_, err queryWithTimeout(ctx, db, SELECT * FROM your_table)if err ! nil {fmt.Println(Query failed:, err)}
}
示例3取消协程
在启动多个 goroutine 进行并发操作时可以通过 context 控制这些 goroutine 的生命周期确保它们能够在必要时被正确取消。
代码示例
package mainimport (contextfmttime
)func operation(ctx context.Context, id int) {select {case -time.After(2 * time.Second):fmt.Printf(Operation %d completed\n, id)case -ctx.Done():fmt.Printf(Operation %d cancelled\n, id)}
}func main() {ctx, cancel : context.WithCancel(context.Background())for i : 0; i 5; i {go operation(ctx, i)}time.Sleep(1 * time.Second)cancel() // 取消所有协程操作time.Sleep(3 * time.Second) // 等待足够的时间以打印完日志观察效果
}
示例4跨服务调用
在微服务架构中一个服务调用另一个服务时可以通过 context 传递关于原始请求的信息如请求ID以便进行链路追踪。
代码示例
package mainimport (contextfmtnet/httptime
)func callService(ctx context.Context, url string) {req, _ : http.NewRequest(GET, url, nil)req req.WithContext(ctx)client : http.Client{}resp, err : client.Do(req)if err ! nil {fmt.Println(Request failed:, err)return}defer resp.Body.Close()fmt.Println(Response status:, resp.Status)
}func main() {ctx : context.Background()ctx context.WithValue(ctx, RequestID, abc123)ctx, cancel : context.WithTimeout(ctx, 1*time.Second)defer cancel()callService(ctx, http://example.com)
}结语
通过这些场景和用法可以看出 context 在 Go 中的重要性特别是在需要控制管理请求生命周期时控制取消。