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

开发 后端
在写 Python 的时候,如果想让某个函数每 60 秒执行一次,我们一般以下三种方式写代码。这种写法,初看起来时跟time.Sleep没什么区别,但是仔细一想,却发现它有很多优势。

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

import time 
 
while True: 
    some_function() 
    time.sleep(60) 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

[[357695]]

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

package main 
 
import ( 
    "fmt" 
    "time" 

 
func someFunction() { 
    fmt.Println("我是某个函数") 

 
func main() { 
    for { 
        someFunction() 
        time.Sleep(10 * time.Second) 
    } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

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

package main 
 
import ( 
    "fmt" 
    "time" 

 
func someFunction() { 
    fmt.Println("我是某个函数") 

 
func main() { 
    tikcer :time.NewTicker(10 * time.Second) 
    for { 
        <-tikcer.C 
        someFunction() 
    } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

这种写法,初看起来时跟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() 
        } 
    } 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.

这样可以实现,每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 
    //其他代码 
    //其他代码 

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.

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

本文转载自微信公众号「未闻Code」,可以通过以下二维码关注。转载本文请联系未闻Code公众号。

 

责任编辑:赵宁宁 来源: 未闻Code
相关推荐

2009-11-13 09:40:27

linux定时执行crontab

2009-12-02 09:17:50

Open Suse

2010-01-07 13:24:22

Linux定时执行工具

2020-12-22 06:04:13

Python定时代码

2023-06-08 08:16:33

TickerPixiJS

2010-06-09 15:15:34

MySQL定时执行

2024-10-07 08:59:47

sleepwait线程

2011-05-04 16:30:07

灵客风LinkPhon

2010-07-02 09:03:52

SQL server定

2012-03-16 15:28:15

DLP云计算数据丢失防御

2012-12-03 09:22:41

KVM服务器虚拟化

2009-02-07 12:23:45

AmazonSimpleDB数据存储

2016-09-09 00:32:57

数据中心软件定义存储

2011-07-08 16:07:41

Oracle job存储过程

2009-09-21 09:57:15

linux进程cron

2011-05-26 15:52:31

sleep()wait()

2023-12-27 08:30:46

Java语言ArkTS

2009-04-01 09:05:34

Java云计算亚马逊EC2

2010-06-25 17:42:08

EclipseEclipse 3.6Java

2021-05-27 10:55:18

IEEdge浏览器
点赞
收藏

51CTO技术栈公众号