MST

星途 面试题库

面试题:Go context的数据结构在并发控制中的应用

在一个复杂的并发程序中,涉及多个goroutine之间的协作与数据传递,利用Go的context数据结构,描述如何实现当某个条件满足时,能快速通知所有相关goroutine进行清理并退出,同时要说明context数据结构的哪些特性有助于实现这样的功能。
50.3万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 实现思路
    • 创建一个 context.Contextcontext.CancelFuncCancelFunc 用于在满足某个条件时取消 context.Context
    • 在每个需要协作的 goroutine 中,传入 context.Context,并在 goroutine 中定期检查 context.ContextDone() 通道。当 Done() 通道可读时,意味着 context 被取消,此时进行清理工作并退出 goroutine
    • 示例代码如下:
package main

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

func worker(ctx context.Context, id int) {
    for {
        select {
        case <-ctx.Done():
            fmt.Printf("Worker %d cleaning up and exiting\n", id)
            return
        default:
            fmt.Printf("Worker %d is working\n", id)
            time.Sleep(1 * time.Second)
        }
    }
}

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

    numWorkers := 3
    for i := 0; i < numWorkers; i++ {
        go worker(ctx, i)
    }

    // 模拟某个条件满足
    time.Sleep(3 * time.Second)
    cancel()

    time.Sleep(2 * time.Second)
}
  1. context数据结构有助于实现此功能的特性
    • 取消机制context.WithCancel 函数返回的 CancelFunc 允许在外部方便地取消 context,从而通知所有依赖该 contextgoroutine。一旦 CancelFunc 被调用,context.ContextDone() 通道会被关闭,所有监听此通道的 goroutine 可以感知到取消信号。
    • 传递性context.Context 可以在不同的 goroutine 之间传递,确保所有相关的 goroutine 都能接收到取消信号。这使得在复杂的并发程序中,能够统一管理多个 goroutine 的生命周期。
    • 超时控制:除了 WithCancelcontext 还有 WithTimeout 等函数,可以设置一个超时时间。当超时时间到达时,context 也会被取消,这在某些需要限制执行时间的场景下非常有用,同样有助于实现 goroutine 的清理和退出。