登录
首页 >  Golang >  Go问答

在 Go 语言中并发地按照时间间隔运行多个函数

来源:stackoverflow

时间:2024-03-26 11:33:38 235浏览 收藏

在 Go 语言中,可以使用 `time.Ticker` 定期触发函数执行。每个函数对应一个间隔时间,使用 goroutine 持续接收事件并调用函数。`schedule` 函数接收函数和间隔时间,创建一个 `time.Ticker` 并启动一个 goroutine 在 ticker 通道上循环调用函数。在主函数中,可以创建多个 `time.Ticker` 并使用 `done` 通道控制 goroutine 的终止。这种方法可用于同时按照指定间隔运行多个函数。

问题内容

我有一个函数列表及其各自的间隔。我想按其时间间隔同时运行每个函数。

在 javascript 中,我写了类似的内容:

maps.forEach(({fn, interval}) => {
    setInterval(fn, interval)
})

如何在 golang 中实现此功能?


解决方案


使用 time.Ticker 定期接收“事件”,您可以用它来计时函数的执行时间。您可以通过拨打time.NewTicker()获取time.ticker。返回的股票有一个定期发送值的通道。

使用 goroutine 不断接收事件并调用函数,例如使用 for range 循环。

让我们看看两个函数:

func onesec() {
    log.println("onesec")
}

func twosec() {
    log.println("twosec")
}

这是一个定期调用给定函数的简单调度程序:

func schedule(f func(), interval time.duration) *time.ticker {
    ticker := time.newticker(interval)
    go func() {
        for range ticker.c {
            f()
        }
    }()
    return ticker
}

使用示例:

func main() {
    t1 := schedule(onesec, time.second)
    t2 := schedule(twosec, 2*time.second)
    time.sleep(5 * time.second)
    t1.stop()
    t2.stop()
}

示例输出(在 Go Playground 上尝试):

2009/11/10 23:00:01 onesec
2009/11/10 23:00:02 twosec
2009/11/10 23:00:02 onesec
2009/11/10 23:00:03 onesec
2009/11/10 23:00:04 twosec
2009/11/10 23:00:04 onesec

请注意,ticker.stop() 不会关闭代码通道,因此 for range 不会终止; stop() 仅停止在股票通道上发送值。

如果你想终止用于调度函数调用的 goroutine,你可以使用额外的通道来实现。然后这些 goroutine 可以使用 select 语句来“监视”股票代码通道和 done 通道,如果从 done 接收成功则返回。

例如:

func schedule(f func(), interval time.duration, done <-chan bool) *time.ticker {
    ticker := time.newticker(interval)
    go func() {
        for {
            select {
            case <-ticker.c:
                f()
            case <-done:
                return
            }
        }
    }()
    return ticker
}

并使用它:

func main() {
    done := make(chan bool)
    t1 := schedule(onesec, time.second, done)
    t2 := schedule(twosec, 2*time.second, done)
    time.sleep(5 * time.second)
    close(done)
    t1.stop()
    t2.stop()
}

Go Playground 上试试这个。

请注意,尽管在这个简单的示例中没有必要停止股票代码(因为 when the main goroutine ends, so does the program with it),但在现实生活中的示例中,如果应用程序继续运行,让股票代码不停止会浪费资源(它们将继续使用后台 goroutine,并将继续尝试在他们的频道上发送价值)。

最后一句话:

如果您有一组函数间隔对,只需使用循环将每对传递给此 schedule() 函数即可。像这样的事情:

type pair struct {
    f        func()
    interval time.Duration
}

pairs := []pair{
    {oneSec, time.Second},
    {twoSec, 2 * time.Second},
}

done := make(chan bool)
ts := make([]*time.Ticker, len(pairs))
for i, p := range pairs {
    ts[i] = schedule(p.f, p.interval, done)
}

time.Sleep(5 * time.Second)
close(done)

for _, t := range ts {
    t.Stop()
}

拨打 Go Playground 试试这个。

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于Golang的相关知识,也可关注golang学习网公众号。

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>