Ticker Or Sleep?定时执行的新选择

简介: Ticker Or Sleep?定时执行的新选择

摄影:产品经理加油站

在写 Python 的时候,如果想让某个函数每 60 秒执行一次,我们一般这样写代码:

import time
while True:
    some_function()
    time.sleep(60)

于是,我在写 Golang 代码的时候,也使用了这种方式:

package main
import (
    "fmt"
    "time"
)
func someFunction() {
    fmt.Println("我是某个函数")
}
func main() {
    for {
        someFunction()
        time.Sleep(10 * time.Second)
    }
}

今天在看同事的代码时,发现他是这样写的:

package main
import (
    "fmt"
    "time"
)
func someFunction() {
    fmt.Println("我是某个函数")
}
func main() {
    tikcer := time.NewTicker(10 * time.Second)
    for {
        <-tikcer.C
        someFunction()
    }
}

这种写法,初看起来时候跟time.Sleep没什么区别,但是仔细一想,却发现它有很多优势。

首先,NewTicker会在背后计时,时间到了以后,会向内部的一个 channel 中推入当前的时间。然后继续计时。所以,如果函数someFunction()执行了3秒钟。那么接下来过7秒就会继续执行。但如果使用time.Sleep,函数执行完成以后,还要再等10秒钟才会执行。

其次,如果不启动新的协程,那么当执行到time.Sleep时,整个程序是卡住的,必须等待它结束了才能执行后面的操作。但如果使用 NewTicker,那么在等待的时间,还可以做很多其他的事情。多个不同的定时器可以同时工作:

package main
import (
    "fmt"
    "time"
)
func someFunction() {
    fmt.Println("我是某个函数")
}
func anotherFunction() {
    fmt.Println("另一个函数")
}
func thirdFunction() {
    fmt.Println("第三个函数")
}
func main() {
    tikcer1 := time.NewTicker(10 * time.Second)
    tikcer2 := time.NewTicker(5 * time.Second)
    tikcer3 := time.NewTicker(3 * time.Second)
    for {
        select {
        case <-tikcer1.C:
            someFunction()
        case <-tikcer2.C:
            anotherFunction()
        case <-tikcer3.C:
            thirdFunction()
        }
    }
}

这样可以实现,每3秒执行 thirdFunction函数,每5秒执行anotherFunction,每10秒执行一次someFunction。大家可以考虑一下,如何用 time.Sleep来实现这样的功能。

注意每个函数都是独立计时的,只要他们执行的时间不超过他们间隔的时间,就不会互相影响。

除了全部用来计时外,我们还可以用来设置外部开关,中断一个协程。例如:

package main
import (
    "fmt"
    "time"
)
func doSomething() {
    fmt.Println("进行某些操作")
}
func someFunction(stop chan bool) {
    fmt.Println("我是某个函数")
    tikcer1 := time.NewTicker(10 * time.Second)
    for {
        select {
        case <-tikcer1.C:
            doSomething()
        case <-stop:
            return
        }
    }
}
func main() {
    stop := make(chan bool)
    go someFunction(stop)
    //很多行代码
    //很多行代码
    //很多行代码
    stop <- true
    //其他代码
    //其他代码
}

在协程里面是一个10秒执行一次的定时函数。但是我们可以在外面控制这个协程,从而随时停止这个协程。

目录
相关文章
Cron表达式范例:每隔5秒执行一次:*/5 * * * * ?
Cron表达式范例: 每隔5秒执行一次:*/5 * * * * ? 每隔1分钟执行一次:0 */1 * * * ? 每天23点执行一次:0 0 23 * * ? ...
5898 0
|
5月前
|
缓存 Java UED
仅执行一次的定时任务如何设置?
【10月更文挑战第12天】仅执行一次的定时任务如何设置?
273 1
|
10月前
|
安全
如何定时关闭程序
该内容是一篇关于如何使用工具进行定时关闭程序的指南。文中提供了两个下载工具的链接,分别来自百度网盘和蓝奏云,附有提取码。操作步骤提到可以参考之前的文章《快捷自由定时重启、注销、关机》,并指出在最后选择“关闭程序”并输入程序名称。此外,还解释了如何找到程序名称的方法,包括通过浏览硬盘和使用任务管理器,强调需添加“.exe”后缀。文中配有多张图片以辅助说明。
|
Java Linux
如何编写一个自动关闭某个进程的脚本,并使用cron定时执行?
如何编写一个自动关闭某个进程的脚本,并使用cron定时执行?
348 0
|
Python
一日一技:为什么不建议使用 time.sleep 实现定时功能?
一日一技:为什么不建议使用 time.sleep 实现定时功能?
201 0
|
NoSQL 算法 Redis
一日一技:除了 time.sleep,你还有一个暂停代码的方法
一日一技:除了 time.sleep,你还有一个暂停代码的方法
187 0
|
Java Spring
使用定时任务 随着项目启动定时执行
使用定时任务 随着项目启动定时执行
341 0
|
数据库
使用at定时执行任务
crontab可以实现周期性地执行任务,如果只需要执行一次任务,那么可以用at。1、安装 yum install at -y 2、启动 service atd start #启动at服务 service atd stop #停止at服务 3、at使用方法 at 时间 命令或者脚本Ctrl+...
856 0
|
监控
crontab设置作业间隔执行问题
这个源于有个网友问,crontab里   */40  9  *  *  *  是不是代表9点开始每40分钟执行?  直觉这个肯定不是从9:00开始每隔40分钟执行一次,但是也不能肯定它代表一个什么样的Schedule,那就做一个实验验证一下吧(有时候明明觉得自己已经掌握了一些知识点,但是总有一些问题,你不能很确切、肯定的回答,其实说明了还有盲点,知识点了解、掌握得不够彻底)。
934 0