MST

星途 面试题库

面试题:Go中Context如何用于控制并发函数的生命周期

在Go并发编程中,假设有一个函数 `func doWork(ctx context.Context)` 用于执行一些任务,该任务可能会持续一段时间。请简述如何使用 `context.Context` 来控制这个函数的生命周期,比如在外部调用方需要取消任务时,`doWork` 函数能够及时感知并结束任务。同时,请写出关键代码片段来展示这一过程。
30.1万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 简述控制过程
    • context.Context 是Go语言中用于在多个 goroutine 之间传递截止时间、取消信号等信息的结构体。
    • 当外部调用方需要取消任务时,会调用取消函数 cancel(),这会向关联的 context.Context 发送取消信号。
    • doWork 函数中的 ctx context.Context 参数会接收到这个取消信号,doWork 函数通过监听 ctx.Done() 通道来感知取消信号,一旦收到取消信号,就及时结束任务。
  2. 关键代码片段
package main

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

func doWork(ctx context.Context) {
    for {
        select {
        case <-ctx.Done():
            fmt.Println("任务被取消,结束工作")
            return
        default:
            fmt.Println("正在工作...")
            time.Sleep(1 * time.Second)
        }
    }
}

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

    // 模拟5秒后取消任务
    time.Sleep(5 * time.Second)
    cancel()
    time.Sleep(1 * time.Second) // 等待doWork函数处理取消信号
}

在上述代码中:

  • context.WithCancel(context.Background()) 创建了一个可取消的 context.Context 以及对应的取消函数 cancel
  • doWork 函数通过 select 语句监听 ctx.Done() 通道,一旦该通道可读,说明任务被取消,doWork 函数就会结束。
  • main 函数中,启动 doWork 函数所在的 goroutine 后,5秒后调用 cancel 函数来取消任务。