您的位置:首页 > 科技 > IT业 > 有什么好的网站推荐一下_赣州章贡区旅游景点_什么是seo和sem_广告推广代运营公司

有什么好的网站推荐一下_赣州章贡区旅游景点_什么是seo和sem_广告推广代运营公司

2025/4/14 15:12:16 来源:https://blog.csdn.net/weixin_51380508/article/details/145508895  浏览:    关键词:有什么好的网站推荐一下_赣州章贡区旅游景点_什么是seo和sem_广告推广代运营公司
有什么好的网站推荐一下_赣州章贡区旅游景点_什么是seo和sem_广告推广代运营公司

超时控制

在 HTTP 请求、数据库查询或 RPC 调用等操作中,防止请求长时间阻塞。

package mainimport ("context""fmt""time"
)func main() {// 设置 2 秒超时ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)defer cancel() // 确保超时后释放资源result := make(chan string)go func() {time.Sleep(3 * time.Second) // 模拟耗时任务result <- "任务完成"}()select {case res := <-result:fmt.Println(res)  // 如果 `result` 先返回数据,就打印结果case <-ctx.Done():fmt.Println("任务超时,取消操作") // 如果 `ctx.Done()` 先触发,说明超时了}
}

context.WithTimeout() 允许在设定时间后自动取消操作,避免 goroutine 长时间阻塞

手动取消

如果一个主 goroutine 需要通知子 goroutine 停止执行,可以使用 context.WithCancel()

package mainimport ("context""fmt""time"
)func worker(ctx context.Context) {for {select {case <-ctx.Done():fmt.Println("收到取消信号,退出")returndefault:fmt.Println("工作中...")time.Sleep(500 * time.Millisecond)}}
}func main() {ctx, cancel := context.WithCancel(context.Background())go worker(ctx)time.Sleep(2 * time.Second)fmt.Println("取消任务")cancel() // 发送取消信号time.Sleep(1 * time.Second) // 等待 goroutine 退出
}在 TCP 服务器中,我们可能需要在主程序退出时,通知所有客户端断开连接。package mainimport ("context""fmt""net""time"
)func handleConnection(ctx context.Context, conn net.Conn) {defer conn.Close()for {select {case <-ctx.Done():fmt.Println("断开客户端连接:", conn.RemoteAddr())returndefault:time.Sleep(1 * time.Second) // 模拟处理fmt.Println("服务客户端:", conn.RemoteAddr())}}
}func main() {ctx, cancel := context.WithCancel(context.Background())ln, err := net.Listen("tcp", ":8080")if err != nil {fmt.Println("监听失败:", err)return}defer ln.Close()go func() {for {conn, err := ln.Accept()if err != nil {fmt.Println("接受连接失败:", err)continue}go handleConnection(ctx, conn)}}()time.Sleep(10 * time.Second) // 服务器运行 10 秒fmt.Println("关闭服务器,断开所有连接")cancel() // 发送取消信号,所有连接都会断开time.Sleep(2 * time.Second) // 等待 goroutine 退出fmt.Println("服务器已关闭")
}

context.WithCancel() 适用于 任务需要手动终止 的场景,如定期任务、消息队列消费等。

传递请求作用域的数据

可以用 context.WithValue() 传递 请求相关的元数据,比如 用户身份信息、trace ID

package mainimport ("context""fmt"
)// 定义一个键的类型,避免键冲突
type contextKey stringfunc processRequest(ctx context.Context) {uid := ctx.Value(contextKey("userID"))fmt.Println("处理请求的用户 ID:", uid)
}func main() {ctx := context.WithValue(context.Background(), contextKey("userID"), 12345)processRequest(ctx)
}

context.WithValue() 适用于 日志追踪、用户身份验证 等场景,但不建议传递大数据结构(会影响性能)。

与 HTTP 服务器结合

在 Web 服务器中,Go 的 http.Request 自带 Context() 方法,可以获取请求的 context,用于控制请求生命周期

package mainimport ("context""fmt""net/http""time"
)func handler(w http.ResponseWriter, r *http.Request) {ctx := r.Context()fmt.Println("处理请求")select {case <-time.After(3 * time.Second):fmt.Fprintln(w, "请求处理完成")case <-ctx.Done():fmt.Fprintln(w, "请求取消")}
}func main() {http.HandleFunc("/", handler)server := &http.Server{Addr: ":8080",}go func() {time.Sleep(2 * time.Second)server.Shutdown(context.Background()) // 2 秒后关闭服务器}()fmt.Println("服务器启动在 8080 端口")if err := server.ListenAndServe(); err != nil {fmt.Println("服务器已关闭")}
}

当客户端断开连接,ctx.Done() 会触发,避免继续执行无用的操作。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com