信号量(Semaphore)
难度:⭐⭐ 中等
考点
- buffered channel 实现信号量
- 并发控制
- Acquire/Release 语义
题目描述
用 buffered channel 实现一个计数信号量,用于限制并发访问数。
要求:
NewSemaphore(n)— 创建允许最多 n 个并发的信号量Acquire()— 获取一个许可,如果没有许可则阻塞TryAcquire(timeout)— 尝试获取,超时返回 falseRelease()— 释放一个许可Available()— 返回当前可用许可数
函数签名
go
type Semaphore struct { ... }
func NewSemaphore(n int) *Semaphore
func (s *Semaphore) Acquire()
func (s *Semaphore) TryAcquire(timeout time.Duration) bool
func (s *Semaphore) Release()
func (s *Semaphore) Available() int提示
- buffered channel 的容量就是信号量的计数
- Acquire = 向 channel 发送(满了就阻塞)
- Release = 从 channel 接收(释放一个位置)
- Available = cap - len
参考答案(Go)
点击展开参考答案
go
//go:build ignore
package answer
import "time"
type Semaphore struct {
ch chan struct{}
}
func NewSemaphore(n int) *Semaphore {
return &Semaphore{ch: make(chan struct{}, n)}
}
func (s *Semaphore) Acquire() {
s.ch <- struct{}{}
}
func (s *Semaphore) TryAcquire(timeout time.Duration) bool {
select {
case s.ch <- struct{}{}:
return true
case <-time.After(timeout):
return false
}
}
func (s *Semaphore) Release() {
<-s.ch
}
func (s *Semaphore) Available() int {
return cap(s.ch) - len(s.ch)
}