MST

星途 面试题库

面试题:Go语言中多协程场景下Go通知退出机制的同步基础问题

在Go语言多协程场景中,假设我们有10个协程同时运行,每个协程执行一些耗时任务。现在需要设计一个基于Go通知退出机制的方案,确保在主程序发出退出信号时,所有协程能安全退出,并且不会出现资源泄露。请描述你的设计思路并给出关键代码片段。
21.8万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 使用context.Context来传递取消信号。context.Context是Go语言中用于控制多个goroutine生命周期的重要工具。
  2. 在主程序中创建一个带有取消功能的context.Context,并将其传递给每个协程。
  3. 每个协程在执行任务时,定期检查context.Context的取消信号,一旦接收到取消信号,立即停止任务执行并进行必要的资源清理。
  4. 使用WaitGroup来等待所有协程完成任务后再退出主程序。

关键代码片段

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 received cancel signal, exiting...\n", id)
            return
        default:
            // 模拟耗时任务
            fmt.Printf("Worker %d is working...\n", id)
            time.Sleep(time.Second)
        }
    }
}

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

    // 启动10个协程
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go worker(ctx, &wg, i)
    }

    // 模拟一段时间后发出退出信号
    time.Sleep(5 * time.Second)
    cancel()

    // 等待所有协程退出
    wg.Wait()
    fmt.Println("All workers have exited, main program exiting.")
}

在上述代码中:

  1. worker函数接收context.ContextWaitGroup,在循环中通过select语句监听ctx.Done()通道,当接收到取消信号时退出循环。
  2. main函数创建了带有取消功能的context.Context,启动10个协程,并在一段时间后调用cancel()函数发出取消信号,最后通过wg.Wait()等待所有协程完成。