MST

星途 面试题库

面试题:Go中WaitGroup如何与Context配合控制并发任务

请描述在Go语言中,如何使用WaitGroup与Context来管理一组并发任务,确保在某个条件满足(通过Context传递信号)时,所有正在执行的并发任务能够安全地停止,并且主程序能够等待这些任务全部完成后再退出。请结合具体的代码示例进行说明。
45.1万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

在Go语言中,WaitGroup 用于等待一组 goroutine 完成,Context 用于在 goroutine 之间传递取消信号等。以下是一个示例代码,展示如何使用它们管理并发任务:

package main

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

func worker(ctx context.Context, wg *sync.WaitGroup, id int) {
    defer wg.Done()
    for {
        select {
        case <-ctx.Done():
            fmt.Printf("Worker %d stopped\n", id)
            return
        default:
            fmt.Printf("Worker %d is working\n", id)
            time.Sleep(100 * time.Millisecond)
        }
    }
}

func main() {
    var wg sync.WaitGroup
    ctx, cancel := context.WithCancel(context.Background())

    numWorkers := 3
    for i := 0; i < numWorkers; i++ {
        wg.Add(1)
        go worker(ctx, &wg, i)
    }

    // 模拟某个条件满足,500毫秒后取消任务
    time.Sleep(500 * time.Millisecond)
    cancel()

    // 等待所有任务完成
    wg.Wait()
    fmt.Println("All workers stopped, main program exiting")
}

在上述代码中:

  1. worker 函数:每个 worker 函数使用 ctx.Done() 通道来监听取消信号。当接收到取消信号时,函数结束,wg.Done() 通知 WaitGroup 该任务已完成。
  2. main 函数
    • 使用 context.WithCancel 创建一个可取消的 Context
    • 启动多个 worker goroutine,并使用 WaitGroup 来跟踪这些 goroutine。
    • 模拟在某个条件满足(这里是等待500毫秒)后,调用 cancel() 函数发送取消信号给所有的 worker goroutine。
    • 最后,wg.Wait() 等待所有 worker goroutine 完成,确保主程序在所有任务完成后再退出。