在 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学习网公众号。
-
502 收藏
-
502 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
139 收藏
-
204 收藏
-
325 收藏
-
478 收藏
-
486 收藏
-
439 收藏
-
357 收藏
-
352 收藏
-
101 收藏
-
440 收藏
-
212 收藏
-
143 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习