123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106 |
- 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)
- }
|