MST

星途 面试题库

面试题:Go语言中如何实现Goroutine的优雅退出

请描述在Go语言里,使用什么方法能够让Goroutine在接收到终止信号时,能够完成当前工作后安全退出,并举例说明。
19.0万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

在Go语言中,可以使用context.Context来实现Goroutine在接收到终止信号时,完成当前工作后安全退出。context.Context主要用于在多个Goroutine之间传递取消信号、截止时间等。

以下是一个简单的示例:

package main

import (
    "context"
    "fmt"
    "os"
    "os/signal"
    "syscall"
    "time"
)

func worker(ctx context.Context) {
    for {
        select {
        case <-ctx.Done():
            fmt.Println("收到终止信号,开始清理工作...")
            // 这里进行清理工作,比如关闭数据库连接等
            time.Sleep(2 * time.Second)
            fmt.Println("清理工作完成,退出")
            return
        default:
            fmt.Println("正在工作...")
            time.Sleep(1 * time.Second)
        }
    }
}

main函数中,创建一个context.Context,并在接收到终止信号时取消该context

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

    go worker(ctx)

    sigs := make(chan os.Signal, 1)
    signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

    go func() {
        sig := <-sigs
        fmt.Println()
        fmt.Println(sig)
        cancel()
    }()

    fmt.Println("按Ctrl+C退出程序")
    select {}
}

在上述代码中:

  1. context.WithCancel(context.Background())创建了一个可取消的context.Context
  2. worker函数中通过select监听ctx.Done()通道,当接收到取消信号时,执行清理工作并退出。
  3. main函数中,通过signal.Notify监听系统信号(如SIGINTSIGTERM),接收到信号后调用cancel()函数取消context,从而通知worker函数退出。