使用信号量可以对一组资源进行访问控制,对于 Go 语言而言,通常使用 sync 包中的 Semaphore 类型来实现信号量。Semaphore 的定义如下:
type Semaphore struct {
ch chan struct{}
}
func NewSemaphore(n int) *Semaphore {
return &Semaphore{make(chan struct{}, n)}
}
func (s *Semaphore) Acquire() {
s.ch <- struct{}{}
}
func (s *Semaphore) Release() {
<-s.ch
}
Semaphore 的 Acquire 方法用于获取资源,如果没有可用资源,则会阻塞直到有资源可用;Release 方法用于释放资源。下面是一个示例,演示如何使用 Semaphore 控制并发执行:
var sem = NewSemaphore(3)
func main() {
for i := 0; i < 10; i++ {
go func(n int) {
sem.Acquire()
defer sem.Release()
fmt.Printf("start task %d\n", n)
time.Sleep(time.Second)
fmt.Printf("finish task %d\n", n)
}(i)
}
time.Sleep(time.Second * 5)
}
在这个示例中,Semaphore 的容量为 3,因此最多同时执行 3 个任务。每个任务在开始时先调用 Acquire 方法获取资源,结束时再调用 Release 方法释放资源。在主函数中,我们让程序休眠 5 秒钟,以确保所有任务都有机会执行完毕。