MST

星途 面试题库

面试题:Go语言中Goroutine的启动方式及简单资源管理

在Go语言中,请描述至少两种启动Goroutine的方式,并说明如何简单地管理Goroutine所占用的资源,比如在Goroutine结束时释放相关资源。
25.6万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 直接启动

    package main
    
    import (
        "fmt"
    )
    
    func worker() {
        fmt.Println("Goroutine is running")
    }
    
    func main() {
        go worker()
        fmt.Println("Main function continues")
    }
    

    在上述代码中,通过go关键字直接启动一个Goroutine,调用worker函数。

  2. 带参数启动

    package main
    
    import (
        "fmt"
    )
    
    func workerWithParam(num int) {
        fmt.Printf("Goroutine with param %d is running\n", num)
    }
    
    func main() {
        for i := 0; i < 5; i++ {
            go workerWithParam(i)
        }
        fmt.Println("Main function continues")
    }
    

    这里启动Goroutine时向函数workerWithParam传递参数。

管理Goroutine所占用资源

  • 使用defer语句:在Goroutine函数内部使用defer关键字来确保相关资源在函数结束时被释放。例如:
    package main
    
    import (
        "fmt"
    )
    
    func resourceHandler() {
        file, err := openFile("example.txt")
        if err != nil {
            return
        }
        defer file.Close()
        // 处理文件的逻辑
        fmt.Println("Processing file...")
    }
    
    func main() {
        go resourceHandler()
        fmt.Println("Main function continues")
    }
    
    这里在打开文件后使用defer来关闭文件,即使resourceHandler函数因各种原因提前结束,文件也能正确关闭。
  • 使用context.Context:可以通过context.Context来控制Goroutine的生命周期,进而释放资源。例如:
    package main
    
    import (
        "context"
        "fmt"
        "time"
    )
    
    func worker(ctx context.Context) {
        for {
            select {
            case <-ctx.Done():
                fmt.Println("Goroutine is cancelled, cleaning up resources")
                // 清理资源的逻辑
                return
            default:
                fmt.Println("Goroutine is working")
                time.Sleep(1 * time.Second)
            }
        }
    }
    
    func main() {
        ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
        defer cancel()
        go worker(ctx)
        time.Sleep(5 * time.Second)
        fmt.Println("Main function continues")
    }
    
    这里通过context.WithTimeout创建一个带超时的上下文,Goroutine中的select语句监听ctx.Done()信号,当信号触发时进行资源清理并结束Goroutine