Go的固定时长定时器和周期性时长定时器

作者:ReganYue 时间:2023-06-27 12:44:23 

我们之前要想在调度里面实现延时执行,我们可以使用管道阻塞,直到有人往管道里面写东西才变通畅,还可以使用sleep来睡觉,但是睡觉的过程,协程啥也干不了也占用资源。所以我们要用到接下来讲的定时器,不会像sleep那样睡的时候也占用资源。

先来看看下面这段代码:


package main

import (
   "fmt"
   "time"
)

func main() {
   timer := time.NewTimer(3 * time.Second)
   fmt.Println("定时器创建完毕!")
   fmt.Println(time.Now())
   //阻塞3秒后才能读出时间
   x := <- timer.C
   //这个C是一个单向的只读管道
   fmt.Println(x)
}

运行结果是这样的:

定时器创建完毕!
2021-08-24 14:02:28.6664158 +0800 CST m=+0.012997601
2021-08-24 14:02:31.670071 +0800 CST m=+3.016652801

我们可以看到,运行结果和我们要达到的目的基本一致,三秒的定时器创建完毕后,阻塞三秒后才能读出时间。

我们来看看这个


x := <- timer.C

根据下面这段代码可知,这个C是一个单向的只读管道:


type Timer struct {
   C <-chan Time
   r runtimeTimer
}

如果要描述一个单向的只写的管道,应该这样写:


C chan <- Time

但是如果要达到同样的目的,我们可以使用下面这种更简单的方式:


func main() {
   fmt.Println(time.Now())
   x := <- time.After(3*time.Second)
   fmt.Println(x)
}

使用time.After()等待规定的一段时间,然后就在返回的管道上发送当前时间。它相当于 NewTimer(d).C。垃圾收集器不会回收底层的 Timer,直到计时器触发才回收。 如果需要考虑效率,请改用 NewTimer 并在不再需要计时器时调用 Timer.Stop来结束。

当然我们也可以使用下面这种方法,两种方法都可以:


x := <- time.NewTimer(3 * time.Second).C

刚才固定时长定时器的就是一个定时 * 设置为三秒钟那三秒钟之后就 * ,现在我们看看周期性时长定时器吧!


func main() {
   ticker := time.NewTicker(1 * time.Second)

   var i int
   for{
       x := <- ticker.C
       fmt.Print("\r",x)
       i++
       if i>3{
           //停掉秒表会导致ticker.C永远无法读出数据,
           //一定要读会导致死锁.
           ticker.Stop()
           break
       }
   }
   fmt.Println("计时结束")
}

这段代码的意思是,设置一个周期性时长定时器,然后每一秒从管道内读一次数据,然后输出直到i>3,就使用ticker.Stop()将定时器结束,然后停止循环,然后告诉你计时结束。

如果将定时器结束后,你仍然要坚持读,就会出现下面这种情况!

fatal error: all goroutines are asleep - deadlock!

出现死锁!所以这里需要用到break.

来源:https://juejin.cn/post/6999881436941516836

标签:Go,定时器
0
投稿

猜你喜欢

  • Dreamweaver MX 2004 试用心得

    2010-03-25 12:21:00
  • [翻译]标记语言和样式手册 Chapter 2 标题

    2008-01-16 11:56:00
  • SQL Server 2000如何设置会话上下文信息?

    2010-05-18 18:33:00
  • 网站鼠标变变变!

    2010-10-20 20:09:00
  • ASP代理采集的核心函数代码

    2010-01-02 20:43:00
  • XML和XSLT结合使网站设计浑然一体

    2008-09-05 17:13:00
  • position两三事

    2009-02-16 15:23:00
  • 详解PHP合并多个PDF文件的方法

    2023-06-15 07:05:22
  • 一空间多域名绑定不同目录方法

    2009-03-09 18:32:00
  • SQL Server 2000安装故障

    2008-01-22 19:10:00
  • 由prototype_1.3.1进入javascript殿堂-类的初探

    2008-05-22 12:44:00
  • FrontPage2002简明教程二:文字与图像的处理

    2008-09-17 11:13:00
  • 在SQL查询中使用LIKE来代替IN查询的方法

    2011-09-30 11:10:18
  • 什么是响应式Web设计?怎样进行?

    2011-11-21 17:00:40
  • DBA_2PC_PENDING 介绍

    2009-02-28 10:59:00
  • SQL离前端有多远?

    2009-05-21 10:37:00
  • IE多版本共存的解决方案——IETester(推荐)

    2009-03-26 12:47:00
  • MySQL权限分配

    2011-01-29 16:37:00
  • 彻底弄懂CSS盒子模式之四(绝对定位和相对定位)

    2007-05-11 16:51:00
  • ASPImage组件的实现过程[图]

    2008-02-03 15:37:00
  • asp之家 网络编程 m.aspxhome.com