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