MST

星途 面试题库

面试题:Go中context取消信号如何在父子goroutine间传递

请描述在Go语言中,如何使用context来管理取消信号在父子goroutine之间的传递,并举出一个简单示例代码说明。
41.3万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

在Go语言中,context包用于在多个goroutine之间传递截止时间、取消信号和其他请求范围的值。要管理取消信号在父子goroutine之间的传递,可以使用context.WithCancel函数。以下是具体步骤和示例代码:

  1. 创建一个context和取消函数: 使用context.WithCancel函数创建一个context和对应的取消函数。这个context会被传递给需要管理取消信号的goroutine

  2. 传递context: 将创建的context传递给子goroutine。子goroutine可以通过监听context.Done()通道来检测是否收到取消信号。

  3. 取消操作: 在父goroutine中,当需要取消子goroutine时,调用取消函数。这会关闭context.Done()通道,从而通知所有监听该通道的goroutine

示例代码如下:

package main

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

func worker(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 worker(ctx)

    // 模拟一些工作
    time.Sleep(3 * time.Second)

    // 取消操作
    cancel()

    // 等待子goroutine完全停止
    time.Sleep(1 * time.Second)
    fmt.Println("程序结束")
}

在上述代码中:

  • context.WithCancel(context.Background())创建了一个可取消的context和对应的取消函数cancel
  • worker函数是一个子goroutine,它通过select语句监听ctx.Done()通道。当该通道接收到值时,意味着收到取消信号,worker函数停止工作。
  • main函数中,启动workergoroutine后,等待3秒,然后调用cancel函数取消context,最后等待1秒确保子goroutine完全停止后程序结束。