因此,我正在编写一个实用程序来查询工作中的API,并且它们每10秒就会限制20次调用。很简单,我将通话限制为自上次通话以来至少经过0.5秒。在尝试使用goroutine之前,我的Throttle实用程序运行良好。
现在我正在使用struct / method组合:
func (c *CTKAPI) Throttle() {
if c.Debug{fmt.Println("\t\t\tEntering Throttle()")}
for { //in case something else makes a call while we're sleeping, we need to re-check
if t := time.Now().Sub(c.LastCallTime); t < c.ThrottleTime {
if c.Debug{fmt.Printf("\t\t\tThrottle: Sleeping %v\n", c.ThrottleTime - t)}
time.Sleep(c.ThrottleTime - t)
} else {
if c.Debug{fmt.Println("\t\t\tThrottle: Released.")}
break
}
}
c.LastCallTime = time.Now()
if c.Debug{fmt.Println("\t\t\tExiting Throttle()")}
}
然后我在每一个goroutine中的每次调用之前调用what.Throttle(),以确保在启动下一个调用之前我已经等待了至少半秒钟。
但这似乎是不可靠的,并且会带来不可预测的结果。有没有更优雅的方法来限制并发请求?
-麦克风
最佳答案
因为要引入数据争用,所以多个例程正在访问/更改c.LastCallTime。
您可以使用 time.Tick
代替,也可以将c.LastCallTime
设置为int64
(c.LastCallTime = time.Now().Unix()
),然后使用atomic.LoadInt64/StoreInt64
进行检查。
关于time - Golang:节气门(时间延迟)功能在goroutine中不起作用(在主线程中正常工作),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28357556/