详解golang 定时任务time.Sleep和time.Tick实现结果比较

总的来说

  • Sleep是使用睡眠完成定时,结束后继续往下执行循环来实现定时任务。
  • Tick函数是使用channel阻塞当前协程,完成定时任务的执行

现在来看一下 两种方法实现出来的效果有何不同

这里我们设置定时时长为5

使用“Do Something” 来模拟定时任务执行需要的时间 分1s执行,10s执行两种情况

代码如下

func Test_Sleep(t *testing.T) {
    for i := 0; i < 3; i++ {
        Debug("begin", time.Now().Format("2006-01-02_15:04:05"))
        Debug("Do something 1s")
        time.Sleep(time.Second * 1)
        Debug("end", time.Now().Format("2006-01-02_15:04:05"))
        time.Sleep(time.Second * 5)
    }
}

func Test_Tick(t *testing.T) {
    t1 := time.NewTicker(5 * time.Second)(5 * time.Second)
    for {
        select {
        case <-t1.C:
            Debug("begin", time.Now().Format("2006-01-02_15:04:05"))
            Debug("Do something 1s")
            time.Sleep(time.Second * 1)
            Debug("end", time.Now().Format("2006-01-02_15:04:05"))
        }
    }
}

Sleep结果1:

2019/04/19 15:58:51 |DEBUG|Test_Sleep()|77|begin 2019-04-19_15:58:51
2019/04/19 15:58:51 |DEBUG|Test_Sleep()|78|Do something 1s
2019/04/19 15:58:52 |DEBUG|Test_Sleep()|80|end 2019-04-19_15:58:52
2019/04/19 15:58:57 |DEBUG|Test_Sleep()|77|begin 2019-04-19_15:58:57
2019/04/19 15:58:57 |DEBUG|Test_Sleep()|78|Do something 1s
2019/04/19 15:58:58 |DEBUG|Test_Sleep()|80|end 2019-04-19_15:58:58
2019/04/19 15:59:03 |DEBUG|Test_Sleep()|77|begin 2019-04-19_15:59:03
2019/04/19 15:59:03 |DEBUG|Test_Sleep()|78|Do something 1s
2019/04/19 15:59:04 |DEBUG|Test_Sleep()|80|end 2019-04-19_15:59:04

设置任务执行时间为1s
end到下一次begin之间的间隔为5s (定时间隔)
其过程大致为:
|DO–>|Sleep---------->|Do–>|Sleep---------->|

Trick结果1

2019/04/19 16:22:09 |DEBUG|Test_Trick()|90|begin 2019-04-19_16:22:09
2019/04/19 16:22:09 |DEBUG|Test_Trick()|91|Do something 1s
2019/04/19 16:22:10 |DEBUG|Test_Trick()|93|end 2019-04-19_16:22:10
2019/04/19 16:22:14 |DEBUG|Test_Trick()|90|begin 2019-04-19_16:22:14
2019/04/19 16:22:14 |DEBUG|Test_Trick()|91|Do something 1s
2019/04/19 16:22:15 |DEBUG|Test_Trick()|93|end 2019-04-19_16:22:15
2019/04/19 16:22:19 |DEBUG|Test_Trick()|90|begin 2019-04-19_16:22:19
2019/04/19 16:22:19 |DEBUG|Test_Trick()|91|Do something 1s
2019/04/19 16:22:20 |DEBUG|Test_Trick()|93|end 2019-04-19_16:22:20

设置任务执行时间为1s
end到下一次begin之间的间隔为4s (定时间隔-任务执行时间)
其过程大致为:
(begin)Do–>(end)
|DO–>-----------|Do–>-------------|
|Sleep---------->|Sleep---------->|

Sleep结果2:

2019/04/19 16:32:41 |DEBUG|Test_Sleep()|77|begin 2019-04-19_16:32:41
2019/04/19 16:32:41 |DEBUG|Test_Sleep()|78|Do something 10s
2019/04/19 16:32:51 |DEBUG|Test_Sleep()|80|end 2019-04-19_16:32:51
2019/04/19 16:32:56 |DEBUG|Test_Sleep()|77|begin 2019-04-19_16:32:56
2019/04/19 16:32:56 |DEBUG|Test_Sleep()|78|Do something 10s
2019/04/19 16:33:06 |DEBUG|Test_Sleep()|80|end 2019-04-19_16:33:06

设置任务执行时间为10s
end到下一次begin之间的间隔为5s (定时间隔)
其过程大致为:
|DO-------------------->|Sleep---------->|Do-------------------->|Sleep---------->|

Trick结果2

2019/04/19 16:41:05 |DEBUG|Test_Tick()|90|begin 2019-04-19_16:41:05
2019/04/19 16:41:05 |DEBUG|Test_Tick()|91|Do something 10s
2019/04/19 16:41:15 |DEBUG|Test_Tick()|93|end 2019-04-19_16:41:15
2019/04/19 16:41:15 |DEBUG|Test_Tick()|90|begin 2019-04-19_16:41:15
2019/04/19 16:41:15 |DEBUG|Test_Tick()|91|Do something 10s
2019/04/19 16:41:25 |DEBUG|Test_Tick()|93|end 2019-04-19_16:41:25

设置任务执行时间为10s
end到下一次begin之间的间隔为0s
此时因为任务执行时间大于定时间隔 当任务执行完毕时 已经没有阻塞 所以可以立马执行下一次
其过程大致为:
(begin)Do–>(end)
|DO-------------------->|Do----------------------->|
|Sleep---------->-------|Sleep---------->---------|

总结

从sleep和tick的实现结果的比较来看 可以发现

1.sleep进行定时任务 任务执行的时间对其实际定时间隔没有影响 睡眠紧跟在任务结束后
2.sleep的定时间隔时间 = 上一个end 到 下一个begin 的时间
3.而tick的实现 使用了一个协程来进行定时 任务执行的时间会对其实际间隔时间产生影响
4.tick的(上一个begin到下一个begin时间) = max (定时间隔时间, 任务执行时间)

至于孰好孰坏 好像一般都是推荐tick 不过还是要看具体的环境再来决定

参考:https://www.jb51.net/article/211330.htm

到此这篇关于详解golang 定时任务time.Sleep和time.Tick实现结果比较的文章就介绍到这了,更多相关golang time.Sleep和time.Tick内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • golang 定时任务方面time.Sleep和time.Tick的优劣对比分析

    golang 写循环执行的定时任务,常见的有以下三种实现方式 1.time.Sleep方法: for { time.Sleep(time.Second) fmt.Println("我在定时执行任务") } 2.time.Tick函数: t1:=time.Tick(3*time.Second) for { select { case <-t1: fmt.Println("t1定时器") } } 3.其中Tick定时任务 也可以先使用time.Ticker函数获取

  • 详解golang 定时任务time.Sleep和time.Tick实现结果比较

    总的来说 Sleep是使用睡眠完成定时,结束后继续往下执行循环来实现定时任务. Tick函数是使用channel阻塞当前协程,完成定时任务的执行 现在来看一下 两种方法实现出来的效果有何不同 这里我们设置定时时长为5 使用“Do Something” 来模拟定时任务执行需要的时间 分1s执行,10s执行两种情况 代码如下 func Test_Sleep(t *testing.T) {     for i := 0; i < 3; i++ {         Debug("begin&quo

  • 一文详解Golang 定时任务库 gron 设计和原理

    目录 cron 简介 gron 定时参数 源码解析 Cron Entry 按照时间排序 新增定时任务 启动和停止 Schedule 扩展性 经典写法-控制退出 结语 cron 简介 在 Unix-like 操作系统中,有一个大家都很熟悉的 cli 工具,它能够来处理定时任务,周期性任务,这就是: cron. 你只需要简单的语法控制就能实现任意[定时]的语义.用法上可以参考一下这个Crontab Guru Editor,做的非常精巧. 简单说,每一个位都代表了一个时间维度,* 代表全集,所以,上面

  • 详解Golang 与python中的字符串反转

    详解Golang 与python中的字符串反转 在go中,需要用rune来处理,因为涉及到中文或者一些字符ASCII编码大于255的. func main() { fmt.Println(reverse("Golang python")) } func reverse(src string) string { dst := []rune(src) len := len(dst) var result []rune result = make([]rune, 0) for i := le

  • 详解Golang 中的并发限制与超时控制

    前言 上回在 用 Go 写一个轻量级的 ssh 批量操作工具里提及过,我们做 Golang 并发的时候要对并发进行限制,对 goroutine 的执行要有超时控制.那会没有细说,这里展开讨论一下. 以下示例代码全部可以直接在 The Go Playground上运行测试: 并发 我们先来跑一个简单的并发看看 package main import ( "fmt" "time" ) func run(task_id, sleeptime int, ch chan st

  • 详解linux 定时任务 crontabs 安装及使用方法

    安装 crontab yum install crontabs centos7 自带了我没有手动去装 启动/关闭 service crond start // 启动服务service crond stop // 关闭服务service crond restart // 重启服务service crond reload // 重新载入配置 查看 crontab 服务是否已设置为开机启动 systemctl list-unit-files | grep enable | grep crond 将 c

  • 详解Golang开启http服务的三种方式

    前言 都说go标准库实用,Api设计简洁.这次就用go 标准库中的net/http包实现一个简洁的http web服务器,包括三种版本. v1最简单版 直接使用http.HandleFunc(partern,function(http.ResponseWriter,*http.Request){}) HandleFunc接受两个参数,第一个为路由地址,第二个为处理方法. //v1 func main() { http.HandleFunc("/", func(w http.Respon

  • 详解Golang中的各种时间操作

    需求 时间格式的转换比较麻烦,自己写了个工具,可以通过工具中的这些方法相互调用转成自己想要的格式,代码如下,后续有新的函数再添加 实现代码 package utils import "time" const ( TIMEFORMAT = "20060102150405" NORMALTIMEFORMAT = "2006-01-02 15:04:05" ) // 当前时间 func GetTime() time.Time{ return time.

  • 详解golang开发中http请求redirect的问题

    这两天在开发项目的时候遇到了一个问题,请求了一个URL,它会302到另一个地址,本意上只是想检查这个URL是否会做3XX的redirect跳转,结果每次reqeust都会返回最后一跳的结果.后来就看了下源码,了解下请求跳转的机制 实现代码 看下实现的简单代码 func main() { client := &http.Client{} url := "http://www.qq.com" reqest, err := http.NewRequest("GET"

  • 详解Golang中Channel的用法

    如果说goroutine是Go语言程序的并发体的话,那么channels则是它们之间的通信机制.一个channel是一个通信机制,它可以让一个goroutine通过它给另一个goroutine发送值信息. 1 创建channel 每个channel都有一个特殊的类型,也就是channels可发送数据的类型.一个可以发送int类型数据 的channel一般写为chan int.使用内置的make函数,如果第二个参数大于0,则表示创建一个带缓存的channel. ch := make(chan in

  • 详解Golang Iris框架的基本使用

    Iris介绍 编写一次并在任何地方以最小的机器功率运行,如Android.ios.Linux和Windows等.它支持Google Go,只需一个可执行的服务即可在所有平台. Iris以简单而强大的api而闻名. 除了Iris为您提供的低级访问权限. Iris同样擅长MVC. 它是唯一一个拥有MVC架构模式丰富支持的Go Web框架,性能成本接近于零. Iris为您提供构建面向服务的应用程序的结构. 用Iris构建微服务很容易. 1. Iris框架 1.1 Golang框架   Golang常用

随机推荐