面试题答案
一键面试基本原理
在Go语言中,信号量(Semaphore)是一种用于控制并发访问资源的机制。其基本原理是通过维护一个计数器,该计数器表示当前可用的资源数量。当一个任务想要访问受信号量保护的资源时,它需要先获取信号量(即计数器减1),如果计数器的值大于0,则获取成功,任务可以继续执行;如果计数器的值为0,则获取失败,任务需要等待,直到有其他任务释放信号量(即计数器加1)。
示例代码
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
semaphore := make(chan struct{}, 5)
for i := 0; i < 10; i++ {
wg.Add(1)
semaphore <- struct{}{}
go func(id int) {
defer func() {
<-semaphore
wg.Done()
}()
fmt.Printf("Task %d is running\n", id)
time.Sleep(1 * time.Second)
fmt.Printf("Task %d is done\n", id)
}(i)
}
wg.Wait()
}
在上述代码中:
semaphore
是一个有缓冲的通道,其缓冲区大小为5,即信号量的初始值为5,表示允许同时执行5个任务。- 在启动每个任务前,向
semaphore
通道发送一个空结构体,这相当于获取信号量,如果通道已满(即信号量为0),则会阻塞,直到有任务释放信号量。 - 每个任务执行完毕后,从
semaphore
通道接收一个空结构体,这相当于释放信号量,让其他等待的任务有机会获取信号量并执行。 sync.WaitGroup
用于等待所有任务完成。