当前位置: 首页 > article >正文

【go从零单排】上下文(context)

挪威特罗姆瑟夜景

🌈Don’t worry , just coding!
内耗与overthinking只会削弱你的精力,虚度你的光阴,每天迈出一小步,回头时发现已经走了很远。

📗概念

在 Go 语言中,上下文(context)是一个重要的概念,主要用于管理请求的生命周期、传递取消信号、超时控制以及传递请求范围内的值。上下文通常与并发编程相关,尤其是在处理 HTTP 请求和其他 I/O 操作时。

💻代码

http上下文

package main

import (
	//fmt:用于格式化输入输出。
	//net/http:提供 HTTP 客户端和服务器的功能。
	//time:用于处理时间相关的功能。
	"fmt"
	"net/http"
	"time"
)

// 定义了一个名为 hello 的处理函数,接受两个参数:
// w http.ResponseWriter:用于构建 HTTP 响应。
// req *http.Request:包含了 HTTP 请求的信息。
func hello(w http.ResponseWriter, req *http.Request) {
	//从请求中获取上下文(Context),用于管理请求的生命周期和处理超时、取消等操作。
	ctx := req.Context()
	//打印日志,表示处理程序开始执行。
	fmt.Println("server: hello handler started")
	//defer 语句确保在函数结束时打印 "server: hello handler ended",即使在函数中发生了错误或提前返回。
	defer fmt.Println("server: hello handler ended")
	//使用 select 语句来处理两个可能的情况:
	select {
	//第一个 case 使用 time.After 创建一个 10 秒的延迟。如果在 10 秒内没有其他事件发生,服务器将向响应写入 "hello"。
	case <-time.After(10 * time.Second):
		fmt.Fprintf(w, "hello\n")
	case <-ctx.Done(): //第二个 case 监听上下文的取消信号。如果请求被取消(例如,客户端关闭了连接),则执行该分支。
		//获取上下文的错误信息(如请求被取消或超时),并打印出来。
		err := ctx.Err()
		fmt.Println("server:", err)
		//使用 http.Error 向客户端返回一个 HTTP 错误响应,状态码为 500(内部服务器错误),并包含上下文的错误信息。
		internalError := http.StatusInternalServerError
		http.Error(w, err.Error(), internalError)
	}
}

func main() {
	//在 main 函数中,使用 http.HandleFunc 注册 /hello 路由,并将其与 hello 处理函数关联。
	http.HandleFunc("/hello", hello)
	//使用 http.ListenAndServe 启动 HTTP 服务器,监听在 8090 端口。
	http.ListenAndServe(":8090", nil)
}

创建和使用上下文

package main

import (
    "context"
    "fmt"
    "time"
)

func main() {
    ctx, cancel := context.WithCancel(context.Background())

    go func() {
        time.Sleep(2 * time.Second)
        cancel() // 取消上下文
    }()

    select {
    case <-time.After(5 * time.Second):
        fmt.Println("Completed without cancellation")
    case <-ctx.Done():
        fmt.Println("Cancelled:", ctx.Err())
    }
}

  • 在这个例子中,创建了一个可取消的上下文 ctx。在一个 Goroutine 中,等待 2 秒后调用 cancel(),这将取消上下文。
  • 主 Goroutine 使用 select 等待 5 秒或上下文的取消信号。

超时控制

package main

import (
    "context"
    "fmt"
    "time"
)

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
    defer cancel() // 确保在函数结束时调用 cancel

    select {
    case <-time.After(3 * time.Second):
        fmt.Println("Completed")
    case <-ctx.Done():
        fmt.Println("Cancelled:", ctx.Err())
    }
}

  • 在这个例子中,创建了一个带有 2 秒超时的上下文。如果在 2 秒内没有完成操作,ctx.Done() 将被触发,主 Goroutine 将打印取消信息。

传递值

package main

import (
    "context"
    "fmt"
)

func main() {
    ctx := context.WithValue(context.Background(), "key", "value")
    value := ctx.Value("key")
    fmt.Println("Value in context:", value)
}


  • 这里创建了一个上下文,并在其中存储了一个键值对。可以通过 ctx.Value(“key”) 获取存储的值。
  • 上下文还可以用于在请求的处理链中传递值,但应谨慎使用,因为上下文的值是不可变的。

💡Tips

Go 的 context 包提供了用于创建和处理上下文的功能。常用的上下文类型有:

  • context.Background():返回一个空的上下文,通常作为根上下文。
  • context.TODO():返回一个空的上下文,表示尚未确定的上下文,适用于开发中的占位符。
  • context.WithCancel(parent):创建一个可取消的上下文。
  • context.WithTimeout(parent,
    timeout):创建一个带有超时的上下文。
  • context.WithDeadline(parent,
    deadline):创建一个带有截止日期的上下文。
  • context.WithValue(parent, key,
    value):创建一个可以传递值的上下文。

💪无人扶我青云志,我自踏雪至山巅。
在这里插入图片描述


http://www.kler.cn/a/393832.html

相关文章:

  • SQL面试题——奔驰SQL面试题 车辆在不同驾驶模式下的时间
  • Linux源码阅读笔记-V4L2框架基础介绍
  • 大数据新视界 -- 大数据大厂之 Impala 性能飞跃:动态分区调整的策略与方法(上)(21 / 30)
  • 【2024软考架构案例题】你知道 Es 的几种分词器吗?Standard、Simple、WhiteSpace、Keyword 四种分词器你知道吗?
  • npm list @types/node 命令用于列出当前项目中 @types/node 包及其依赖关系
  • DevOps工程技术价值流:加速业务价值流的落地实践与深度赋能
  • Linux:测试指令test
  • Kafka可视化kafka-eagle的安装使用
  • 【划分型DP-约束划分个数】【hard】力扣410. 分割数组的最大值
  • cmake报错The link interface of target “gRPC::grpc“ contains: OpenSSL::SSL 解决
  • 西门子PLC更新DB块时不初始化变量
  • RSTP技术
  • Javascript如何获取指定网页中的内容?
  • 从无音响Windows 端到 有音响macOS 端实时音频传输播放
  • JavaScript判断数组的方式有哪些
  • 数字孪生技术在城市规划中的应用
  • SystemVerilog学习笔记(五):运算符
  • 第二十周机器学习笔记:初步认识PINN
  • Ajax 与 Vue 框架应用点——随笔谈
  • Github 2024-11-09Rust开源项目日报 Top10
  • pgsql和mysql的自增主键差异
  • neo4j desktop基本入门
  • RTPS网卡白名单的一个BUG
  • Mybatis经典面试题汇总
  • Altium Designer使用技巧(五)
  • SQL Server 的结构,现在看也不算差