go-resiliency源码解析之-semaphore
1.什么是semaphore
这个是我问ChatGPT的文档
Semaphore 是一种用于同步进程间共享资源的机制。Semaphore 可以看作是一个计数器,用于保护一定数量的共享资源。当进程需要访问共享资源时,它必须先从 Semaphore 中获取一个许可证,然后才能访问共享资源。当进程完成了对共享资源的访问后,它必须将许可证返还给 Semaphore。Semaphore 可以防止多个进程同时访问共享资源,从而避免了竞争条件的发生,保证了程序的正确性和可靠性。Semaphore 是多进程编程中常用的技术之一。
简单来说信号量是用于并发控制,保护并发资源的一种机制。常用的并发机制有,互斥量,读写锁,信号量这些都是单进程里的锁机制,在分布式系统下还有分布式锁。
2.go-resiliency的semaphore实现
创建一个semaphore需要两个参数:
- ticket count (一次发放多少张票),协程只有在获取到票据才能访问共享资源。
- timeout (如果目前没有票,要等多久才有票),超过timeout的等待返回超时。
type Semaphore struct {
sem chan struct{}
timeout time.Duration
}
func New(tickets int, timeout time.Duration) *Semaphore {
//这里使用chan特性来模拟信号量的票据,创建一个tickets待缓冲的chan
return &Semaphore{
sem: make(chan struct{}, tickets),
timeout: timeout,
}
}
//每次在访问共享,需要调用Acquire函数,在Acquire函数里如果能写入chan成功,说明获取到票据
//否则在这里等待,在timeout时间后会超时返回
func (s *Semaphore) Acquire() error {
select {
case s.sem <- struct{}{}:
return nil
case <-time.After(s.timeout):
return ErrNoTickets
}
}
//在使用完资源后需要调用Release返回票据
func (s *Semaphore) Release() {
<-s.sem
}