package xugu import ( "sync" "time" ) /* 定义信号量结构体:Sema 结构体包含一个 sync.Mutex 和一个 sync.Cond,以及一个计数器 count。 初始化信号量:initSema 和 initSemaN 函数用于初始化信号量,并设置信号量初始值。 减少信号量(等待):decSema 函数用于减少信号量,当信号量为 0 时阻塞。 增加信号量:incSema 函数用于增加信号量,并通知等待的 goroutine。 等待信号量:waitSema 函数调用 decSema 实现等待。 带超时的等待信号量:waitSemaT 函数实现带超时的等待信号量操作。 清除信号量:clrSema 函数将信号量计数器置为 0。 关闭信号量:在 Go 中不需要显式销毁信号量。 模拟 usleep 函数:sleep 函数使用 time.Sleep 模拟 usleep。 */ // 定义信号量结构体 type Sema struct { mutex sync.Mutex cond *sync.Cond count int } // 初始化信号量 func initSema() *Sema { sema := &Sema{} sema.cond = sync.NewCond(&sema.mutex) return sema } // 初始化信号量,并设置信号量初始值 func initSemaN(n int) *Sema { sema := &Sema{count: n} sema.cond = sync.NewCond(&sema.mutex) return sema } // 减少信号量(等待) func (s *Sema) decSema() { s.mutex.Lock() for s.count == 0 { s.cond.Wait() } s.count-- s.mutex.Unlock() } // 增加信号量 func (s *Sema) incSema() { s.mutex.Lock() s.count++ s.cond.Signal() s.mutex.Unlock() } // 等待信号量 func (s *Sema) waitSema() { s.decSema() } // 带超时的等待信号量 func (s *Sema) waitSemaT(timeout time.Duration) bool { s.mutex.Lock() defer s.mutex.Unlock() timer := time.NewTimer(timeout) defer timer.Stop() for s.count == 0 { timer.Reset(timeout) select { case <-timer.C: return false case <-func() chan struct{} { ch := make(chan struct{}) go func() { s.cond.Wait() close(ch) }() return ch }(): } } s.count-- return true } // 清除信号量 func (s *Sema) clrSema() { s.mutex.Lock() for s.count > 0 { s.count-- } s.mutex.Unlock() } // 关闭信号量(销毁信号量) func (s *Sema) closeSema() { // 在 Go 中不需要显式销毁信号量 } // 模拟 usleep 函数 func sleep(t int) { time.Sleep(time.Duration(t) * time.Millisecond) }