面试题答案
一键面试- 资源管理策略:
- 限制goroutine数量:通过信号量(semaphore)机制来限制同时运行的goroutine数量。信号量可以看作是一个计数器,它记录了当前可用的资源数量(在这里就是允许同时运行的goroutine数量)。当一个goroutine想要开始执行时,它需要先获取信号量(将计数器减1),如果计数器为0,则表示资源已被占用,该goroutine需要等待。当goroutine执行完毕后,它会释放信号量(将计数器加1),这样其他等待的goroutine就有机会获取信号量并开始执行。
- 资源清理:在goroutine内部,要确保及时清理不再使用的资源,如关闭文件描述符、数据库连接等,避免资源泄漏。
- Go代码示例:
package main
import (
"fmt"
"sync"
)
// Semaphore结构体表示信号量
type Semaphore struct {
tokens chan struct{}
}
// NewSemaphore创建一个指定数量令牌的信号量
func NewSemaphore(n int) *Semaphore {
return &Semaphore{
tokens: make(chan struct{}, n),
}
}
// Acquire获取一个信号量令牌,如果没有可用令牌则阻塞
func (s *Semaphore) Acquire() {
s.tokens <- struct{}{}
}
// Release释放一个信号量令牌
func (s *Semaphore) Release() {
<-s.tokens
}
func main() {
// 创建一个最多允许3个goroutine同时运行的信号量
sem := NewSemaphore(3)
var wg sync.WaitGroup
// 模拟10个扇出任务
for i := 0; i < 10; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
sem.Acquire()
defer sem.Release()
// 模拟任务执行
fmt.Printf("Goroutine %d is running\n", id)
}(i)
}
wg.Wait()
fmt.Println("All goroutines have finished")
}
在上述代码中:
Semaphore
结构体包含一个tokens
通道,用于表示可用的信号量令牌。NewSemaphore
函数创建一个指定数量令牌的信号量。Acquire
方法获取一个信号量令牌,如果没有可用令牌则阻塞。Release
方法释放一个信号量令牌。- 在
main
函数中,创建了一个最多允许3个goroutine同时运行的信号量,并启动10个goroutine,每个goroutine在执行前先获取信号量,执行完毕后释放信号量,以此来限制同时运行的goroutine数量。