Golang:油门(延时)功能在 goroutine 中不起作用(在主线程中工作正常)

所以我正在编写一个实用程序来查询工作中的 API,它们每 10 秒限制为 20 次调用。很简单,我只会将我的通话限制在自上次通话以来至少过去 0.5 秒。在我尝试使用 goroutines 之前,我的 Throttle 实用程序运行良好。


现在我正在使用结构/方法组合:


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() 以确保在启动下一个调用之前我已经等待了至少半秒。


但这似乎不可靠并且会产生不可预测的结果。有没有更优雅的方式来限制并发请求?


-麦克风


白板的微信
浏览 168回答 3
3回答

偶然的你

实际上有一个更简单的方法来做到这一点:创建一个时间行情。package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "sync"&nbsp; &nbsp; "time")func main() {&nbsp; &nbsp; rateLimit := time.Tick(500 * time.Millisecond)&nbsp; &nbsp; <-rateLimit&nbsp; &nbsp; var wg sync.WaitGroup&nbsp; &nbsp; for i := 0; i < 10; i++ {&nbsp; &nbsp; &nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; &nbsp; &nbsp; go func(i int) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <-rateLimit&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("Hello", i)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wg.Done()&nbsp; &nbsp; &nbsp; &nbsp; }(i)&nbsp; &nbsp; }&nbsp; &nbsp; wg.Wait()}

慕尼黑8549860

因为您正在引入数据竞争,所以多个例程正在访问/更改 c.LastCallTime。您可以time.Tick改用或制作c.LastCallTime一个int64(&nbsp;c.LastCallTime = time.Now().Unix()) 并用于atomic.LoadInt64/StoreInt64检查它。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go