也许你可以使用 Sync.Mutex 和 time.After 来实现一个 Throttler,如下所示
package main
import (
"fmt"
"os"
"os/signal"
"sync"
"syscall"
"time"
)
type Throttler struct {
invocations int
duration time.Duration
m sync.Mutex
max int
}
func (t *Throttler) Throttle() {
t.m.Lock()
defer t.m.Unlock()
t.invocations += 1
if t.invocations >= t.max {
<-time.After(t.duration) // This block until the time period expires
t.invocations = 0
}
}
func main() {
t := &Throttler{
max: 2,
duration: time.Second,
}
// Launch your workers passing in the throttler created above.
for i := 0; i < 10; i++ {
fmt.Println("starting worker")
go Worker(t);
}
// This just to prevent the main from exiting.
c := make(chan os.Signal)
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
<-c // This will block until you manually exists with CRl-C
}
// worker
func Worker(t *Throttler) {
t.Throttle()
fmt.Println("Work done!!")
}