面试题答案
一键面试实现思路
- 在每个goroutine中监听通道关闭信号:通过
for... range
循环或者使用select
语句结合ok
标志来检测通道是否关闭。 - 资源释放逻辑:一旦检测到通道关闭,在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
完成资源释放。