MST

星途 面试题库

面试题:Go语言通道关闭对并发资源释放的影响

假设你有多个goroutine通过一个通道进行通信,当通道关闭时,这些goroutine如何优雅地释放它们所占用的资源(例如文件句柄、网络连接等)?描述实现思路,并给出关键代码片段。
27.8万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 在每个goroutine中监听通道关闭信号:通过for... range循环或者使用select语句结合ok标志来检测通道是否关闭。
  2. 资源释放逻辑:一旦检测到通道关闭,在goroutine内执行资源释放的代码,例如关闭文件句柄、断开网络连接等。

关键代码片段

package main

import (
    "fmt"
    "os"
)

func worker(id int, dataCh <-chan int, doneCh chan<- struct{}) {
    file, err := os.Open("example.txt")
    if err != nil {
        fmt.Printf("Worker %d: failed to open file\n", id)
        return
    }
    defer file.Close()

    for data, ok := <-dataCh; ok; data, ok = <-dataCh {
        fmt.Printf("Worker %d received data: %d\n", id, data)
    }

    // 通道关闭,释放资源
    fmt.Printf("Worker %d: channel closed, releasing resources\n", id)
    // 这里可以添加更多资源释放逻辑,如关闭网络连接等
    doneCh <- struct{}{}
}

func main() {
    dataCh := make(chan int)
    doneCh := make(chan struct{}, 3)

    // 启动多个goroutine
    for i := 1; i <= 3; i++ {
        go worker(i, dataCh, doneCh)
    }

    // 发送数据
    for i := 1; i <= 5; i++ {
        dataCh <- i
    }

    // 关闭通道
    close(dataCh)

    // 等待所有goroutine完成资源释放
    for i := 1; i <= 3; i++ {
        <-doneCh
    }
    close(doneCh)

    fmt.Println("All workers have released resources")
}

在上述代码中:

  • worker函数模拟了一个工作的goroutine,它打开一个文件(模拟占用资源),并通过dataCh通道接收数据。
  • 使用for... range循环监听dataCh通道,当通道关闭时,循环结束,此时执行资源释放逻辑(这里是关闭文件)。
  • 主函数中启动多个worker goroutine,发送数据后关闭dataCh通道,然后通过doneCh通道等待所有worker完成资源释放。