MST

星途 面试题库

面试题:Go语言中context如何实现并发控制的取消操作

请描述在Go语言中使用context包,如何实现一个子goroutine的取消操作。假设你有一个长时间运行的任务在goroutine中执行,当接收到外部信号(例如用户点击取消按钮模拟的信号)时,该goroutine能够优雅地停止执行。请给出相关代码示例并解释其原理。
15.0万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

代码示例

package main

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

func longRunningTask(ctx context.Context) {
    for {
        select {
        case <-ctx.Done():
            fmt.Println("任务被取消")
            return
        default:
            fmt.Println("任务正在执行...")
            time.Sleep(1 * time.Second)
        }
    }
}

main函数中调用:

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

    go longRunningTask(ctx)

    time.Sleep(3 * time.Second)
    cancel()

    time.Sleep(2 * time.Second)
}

原理解释

  1. 创建context:通过context.WithCancel(context.Background())创建一个可取消的contextcontext.Background()是所有context的根,WithCancel函数返回一个context和一个取消函数cancel
  2. 在goroutine中使用context:在longRunningTask函数中,通过select语句监听ctx.Done()通道。当ctx.Done()通道接收到数据时,意味着context被取消,此时可以进行清理操作并退出goroutine
  3. 取消操作:在main函数中,通过调用cancel()函数来取消context,这会向ctx.Done()通道发送数据,从而通知正在执行的goroutine停止任务。time.Sleep语句用于模拟实际应用场景中的等待和操作。