面试题答案
一键面试初始化信号量
在Go语言中,可以通过创建一个带有缓冲区的channel来模拟信号量。缓冲区的大小即为信号量的初始值。
func NewSemaphore(capacity int) chan struct{} {
return make(chan struct{}, capacity)
}
获取信号量
获取信号量意味着从channel中接收一个值。如果channel为空(没有可用信号量),接收操作会阻塞,直到有信号量被释放。
func Acquire(semaphore chan struct{}) {
semaphore <- struct{}{}
}
释放信号量
释放信号量就是向channel中发送一个值,增加可用的信号量。
func Release(semaphore chan struct{}) {
<-semaphore
}
完整示例代码
package main
import (
"fmt"
"sync"
"time"
)
func NewSemaphore(capacity int) chan struct{} {
return make(chan struct{}, capacity)
}
func Acquire(semaphore chan struct{}) {
semaphore <- struct{}{}
}
func Release(semaphore chan struct{}) {
<-semaphore
}
func worker(id int, semaphore chan struct{}, wg *sync.WaitGroup) {
defer wg.Done()
Acquire(semaphore)
fmt.Printf("Worker %d acquired the semaphore\n", id)
time.Sleep(time.Second)
fmt.Printf("Worker %d released the semaphore\n", id)
Release(semaphore)
}
func main() {
semaphore := NewSemaphore(3)
var wg sync.WaitGroup
for i := 1; i <= 5; i++ {
wg.Add(1)
go worker(i, semaphore, &wg)
}
wg.Wait()
}
在上述代码中:
NewSemaphore
函数创建一个带有指定缓冲区大小的channel来初始化信号量。Acquire
函数尝试获取信号量,通过向channel发送一个空结构体来占用信号量。Release
函数释放信号量,通过从channel接收一个值来归还信号量。- 在
main
函数中,创建了一个容量为3的信号量,并启动5个goroutine来模拟并发操作,每个goroutine获取信号量、执行一些工作,然后释放信号量。