因此,我正在编写一个实用程序来查询工作中的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/

10-12 00:21
查看更多