MST
星途 面试题库

面试题:Go中context如何在并发函数间传递取消信号

在Go语言中,当使用`context`管理并发时,假设有多个并发函数,如`func1`、`func2`、`func3`通过`go`关键字启动。请描述如何创建一个`context`对象,并将其传递给这些并发函数,使得在主函数的某个时刻,能够向所有这些并发函数发送取消信号,并且这些函数能正确响应取消信号并安全退出。
35.2万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 创建context对象并传递取消函数: 在主函数中使用context.WithCancel函数创建一个可取消的context对象和对应的取消函数。示例代码如下:
    package main
    
    import (
        "context"
        "fmt"
        "time"
    )
    
    func func1(ctx context.Context) {
        for {
            select {
            case <-ctx.Done():
                fmt.Println("func1收到取消信号,退出")
                return
            default:
                fmt.Println("func1正在执行")
                time.Sleep(1 * time.Second)
            }
        }
    }
    
    func func2(ctx context.Context) {
        for {
            select {
            case <-ctx.Done():
                fmt.Println("func2收到取消信号,退出")
                return
            default:
                fmt.Println("func2正在执行")
                time.Sleep(1 * time.Second)
            }
        }
    }
    
    func func3(ctx context.Context) {
        for {
            select {
            case <-ctx.Done():
                fmt.Println("func3收到取消信号,退出")
                return
            default:
                fmt.Println("func3正在执行")
                time.Sleep(1 * time.Second)
            }
        }
    }
    
    func main() {
        ctx, cancel := context.WithCancel(context.Background())
    
        go func1(ctx)
        go func2(ctx)
        go func3(ctx)
    
        time.Sleep(3 * time.Second)
        cancel() // 发送取消信号
        time.Sleep(2 * time.Second) // 等待所有函数退出
    }
    
  2. 在并发函数中响应取消信号: 在func1func2func3函数内部,通过select语句监听ctx.Done()通道。当该通道接收到数据时,说明收到了取消信号,此时函数可以进行必要的清理工作并安全退出。

在上述代码中:

  • 首先在main函数中使用context.WithCancel(context.Background())创建了一个可取消的context对象ctx和取消函数cancel
  • 然后通过go关键字启动func1func2func3并发函数,并将ctx作为参数传递进去。
  • main函数中等待3秒后调用cancel()函数,向所有并发函数发送取消信号。
  • func1func2func3函数内部通过select监听ctx.Done()通道,收到取消信号后打印信息并退出循环,从而安全退出函数。