MST

星途 面试题库

面试题:Go语言中Context的主要作用是什么

请阐述Go语言中Context在实际编程场景中的主要用途,并举例说明在一个简单的HTTP服务器处理函数中如何使用Context来控制请求的生命周期。
42.7万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

Context在Go语言实际编程场景中的主要用途

  1. 控制请求生命周期:在处理请求时,通过Context可以在不同的函数调用层级间传递请求的取消信号。当客户端关闭连接或者超时等情况发生时,上层函数可以通过取消Context来通知下层函数及时清理资源并返回,避免不必要的计算和资源占用。
  2. 传递请求范围数据:Context可以携带一些与请求相关的数据,如认证信息、请求ID等,方便在整个请求处理的链条中各个函数都能访问到这些数据,而不需要通过层层传递参数的方式。
  3. 设置截止时间:可以为一个操作设置截止时间,当超过这个时间后,操作自动取消,避免长时间阻塞。

在HTTP服务器处理函数中使用Context控制请求生命周期示例

package main

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

func handler(w http.ResponseWriter, r *http.Request) {
    // 获取请求的上下文
    ctx := r.Context()

    // 创建带有取消功能的上下文
    ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
    defer cancel()

    // 模拟一个可能长时间运行的任务
    done := make(chan struct{})
    go func() {
        time.Sleep(10 * time.Second)
        close(done)
    }()

    select {
    case <-ctx.Done():
        // 如果上下文取消,说明请求超时或被取消
        fmt.Fprintf(w, "Request cancelled or timed out: %v\n", ctx.Err())
        return
    case <-done:
        // 如果任务正常完成
        fmt.Fprintf(w, "Request completed successfully\n")
    }
}

func main() {
    http.HandleFunc("/", handler)
    fmt.Println("Server listening on :8080")
    http.ListenAndServe(":8080", nil)
}

在上述代码中:

  1. 首先通过r.Context()获取请求的上下文。
  2. 然后使用context.WithTimeout创建一个带有5秒超时的新上下文,并通过defer cancel()确保在函数结束时取消这个上下文,释放相关资源。
  3. 模拟一个10秒的长时间运行任务,通过select语句监听上下文取消信号ctx.Done()和任务完成信号done。如果上下文先取消,说明请求超时或被取消,返回相应提示;如果任务先完成,则返回成功提示。