首页 > 其他分享 >Go:context.Context

Go:context.Context

时间:2024-11-24 11:11:10浏览次数:6  
标签:Context 取消 userID ctx 任务 context Go 超时

什么是 context

context 是 Go 标准库中用来管理任务生命周期跨 API 数据传递的工具。它的主要应用场景是在并发编程中,尤其是处理像 HTTP 请求这样有超时限制或需要手动取消的任务。

为了更通俗地理解,可以把 context 想象成一个任务的「管理员」,它可以:

  1. 通知任务何时结束(比如超时或取消时)。
  2. 传递一些全局信息(比如用户身份或配置)。

从常用例子开始

1. HTTP 请求中的超时控制

假设我们正在写一个 HTTP 服务器,客户端请求要求超时 2 秒:

package main

import (
	"context"
	"fmt"
	"net/http"
	"time"
)

func handler(w http.ResponseWriter, r *http.Request) {
	// 创建一个带超时的 context,2 秒后自动取消
	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
	defer cancel() // 确保函数结束时释放资源

	// 模拟一个耗时任务
	select {
	case <-time.After(3 * time.Second):
		fmt.Fprintln(w, "Finished task")
	case <-ctx.Done(): // 当 context 超时时,Done 会被触发
		http.Error(w, "Request timed out", http.StatusRequestTimeout)
	}
}

func main() {
	http.HandleFunc("/", handler)
	http.ListenAndServe(":8080", nil)
}

运行逻辑:

  • 如果任务完成时间超过 2 秒,ctx.Done() 会收到取消信号,及时停止任务,避免资源浪费。
  • context 帮助我们优雅地处理超时。

2. 跨 API 传递请求信息

context 还能传递数据,比如用户的认证信息或请求 ID:

package main

import (
	"context"
	"fmt"
)

func main() {
	// 创建一个带键值对的 context
	ctx := context.WithValue(context.Background(), "userID", 42)

	// 传递 context 到其他函数
	processRequest(ctx)
}

func processRequest(ctx context.Context) {
	// 从 context 中取出数据
	if userID := ctx.Value("userID"); userID != nil {
		fmt.Println("Processing request for user:", userID)
	} else {
		fmt.Println("No user ID found")
	}
}

运行逻辑:

  • 主函数设置了 userID,传递给 processRequest
  • 在子函数中,可以从 context 中提取出该数据,实现信息的跨 API 共享。

context 的关键功能

  1. 取消信号
    使用 context.WithCancel 来手动通知任务停止:

    ctx, cancel := context.WithCancel(context.Background())
    go func() {
        time.Sleep(1 * time.Second)
        cancel() // 通知任务取消
    }()
    
    <-ctx.Done() // 阻塞,直到取消信号被触发
    fmt.Println("Task cancelled")
    
  2. 超时控制
    使用 context.WithTimeout 自动取消任务:

    ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    defer cancel()
    
    select {
    case <-time.After(3 * time.Second):
        fmt.Println("Task completed")
    case <-ctx.Done():
        fmt.Println("Timeout:", ctx.Err()) // 输出超时错误
    }
    
  3. 数据传递
    使用 context.WithValue 跨 API 传递数据。


为什么需要 context

  1. 解决并发中的控制问题
    在 Go 中,任务往往是通过 goroutine 并发执行的,但如何优雅地终止任务?传统方法可能需要复杂的 channel 通信,而 context 提供了一个统一的接口。

  2. 统一超时和取消机制
    无需手动编写超时逻辑或全局变量,context 内置了这些功能。

  3. 跨 API 共享数据
    context 可以像字典一样存储键值对,让函数间更方便地传递信息。


常用场景

  1. HTTP 请求处理:
    控制请求的超时、取消和数据传递。

  2. 数据库操作:
    遇到慢查询时,设置超时或取消。

  3. 微服务通信:
    在分布式系统中传递请求 ID 或认证信息。

  4. 并发任务协调:
    例如多个 goroutine 需要根据同一个取消信号停止。


总结

通俗来说,context 是 Go 语言中用来管理任务生命周期传递信息的工具,它让我们可以更方便地实现超时控制、手动取消和跨 API 数据共享,简化了并发编程中的复杂操作。

标签:Context,取消,userID,ctx,任务,context,Go,超时
From: https://www.cnblogs.com/niumachen/p/18565558

相关文章

  • Google账号注册教程
    开篇:去搜索了下注册教程,发现找不到我原本学习的博客了,没找到我注册的版本博客了,决定手写一个,嘿嘿,成功了别忘了回来留下你的评论前提:能使用Google搜索引擎(魔法),不能使用那就收藏吧,以后肯定会用到的首先进入创建Google账号的界面,点击创建账号,选择个人用途姓氏可......
  • django的model时间怎么转时间戳
    在Django中,模型(Model)中的日期和时间字段通常使用Django的DateTimeField或相关字段来存储。如果你想要将这些日期时间字段转换为Unix时间戳(即自1970年1月1日以来的秒数),你可以使用Python的datetime模块中的timestamp()方法。以下是一个例子,展示了如何将Django模型中的DateTim......
  • 2024年11月17日 星期天 Go语言基础
    今日格言坚持每天进步一点点~一个人也可以是一个团队~学习全栈开发,做自己喜欢的产品~~Go语言的创始人Go语言的创始人有三位,分别是:RobertGriesemer:他参与开发了JavaHotSpot虚拟机。RobPike:他是Go语言项目的总负责人,曾是贝尔实验室Unix团队的成员,参与过Plan9、Inf......
  • Google Play养号:2024最新攻略
    GooglePlay的监测越来越严格,如果账号状态不稳定或权重过低,不仅不利于应用审核和发布,还可能导致应用曝光受限,甚至应用在GooglePlay上被移除、账号无法发布新应用或重新发布已有应用。因此,Google Play养号是十分重要的,从多方面提升账号权重,可以参考以下内容。一、基本操作......
  • 40分钟学 Go 语言高并发:Context包与并发控制
    Context包与并发控制学习目标知识点掌握程度应用场景context原理深入理解实现机制并发控制和请求链路追踪超时控制掌握超时设置和处理API请求超时、任务限时控制取消信号传播理解取消机制和传播链优雅退出、资源释放context最佳实践掌握使用规范和技巧工程实践中的常见场......
  • go语言的成神之路-筑基篇-第一章
    目录第一节-家族的屈辱第二节-初见go语言第三节-初识gin框架 GET请求​编辑 POST请求 PUT请求DELETE请求第四节-template的初识main函数代码html代码效果展示  第五节-总结LOGO在这个设计中,引入了一只更加优雅的绿色蜥蜴(Gopher),它身披金色斗篷,手持象征......
  • Springboot集成Mongodb
    1、安装Mongodb参考链接:https://www.cnblogs.com/lveyHang/p/16866309.html2、进行配置找到mongodb的安装位置、找到如下文件进行配置 Mongodb\bin\mongod.cfg#配置数据存储目录,没有则创建.storage:dbPath:D:\soft\Mongodb\data#配置日志存储目录,没有则创建.systemLo......
  • Typora-PicGo-OSS对象存储
    Typora-PicGo-对象存储OSS问题描述:上次做完Gitee图床配置后,今天发现图床突然不能使用了,直到我查找到Gitee仓库变成私有后才发现做的图床被封禁了当前仓库因涉嫌外链滥用(RAW),不支持设置为公开仓库,就导致我的笔记链接的图片全部失效。这令我很头疼,毕竟是当时为了能够免费使......
  • MongoDB身份认证机制揭秘!
    检查MongoDB服务器的身份验证状态,使用MongoDB的shell或者命令行工具。1使用MongoDBShell1.1连接到admin数据库因为大多数身份验证相关的命令需要在admin数据库中运行:useadmin1.2检查服务器的身份验证状态db.runCommand({getParameter:1,authenticationMechanisms:1......
  • 使用Go语言实现基本图像识别
    Go语言(又叫Golang)是一种由Google开发的编程语言,以简洁、效率和并发为特点。以下是使用Go语言实现Sobel边缘检测的代码示例。代码实现以下代码使用Go语言结合image,image/color,image/draw库来处理图像。go更多内容访问ttocr.com或联系1436423940packagemainimport("fmt......