go语言如何设置定时器


本文摘自php中文网,作者藏色散人,侵删。

go语言设置定时器的方法:1、通过“time.NewTicker()”方法创建,其中ticker会按照设定的间隔时间触发;2、通过“time.NewTimer()”方法创建,其中timer只会执行一词;3、使用“After()”来创建。

本文环境:Windows7系统、Go1.11.2版,本文适用于所有品牌的电脑。

推荐:《golang教程

Go语言中定时器的使用

GO语言在time包中提供了三种定时器的使用方式:

1.第一种:ticker

1

2

3

4

5

6

// A Ticker holds a channel that delivers `ticks' of a clock

// at intervals.

type Ticker struct {

    C <-chan Time // The channel on which the ticks are delivered.

    r runtimeTimer

}

通过 time.NewTicker() 创建,这种类型,ticker会不断的按照设定的间隔时间触发,除非主动终止运行。

2.第二种:timer

1

2

3

4

5

6

7

8

// The Timer type represents a single event.

// When the Timer expires, the current time will be sent on C,

// unless the Timer was created by AfterFunc.

// A Timer must be created with NewTimer or AfterFunc.

type Timer struct {

    C <-chan Time

    r runtimeTimer

}

通过 time.NewTimer() 创建,这种类型,timer只会执行一次,当然,可以在执行完以后通过调用 timer.Reset() 让定时器再次工作,并可以更改时间间隔。

3.第三种:After()

1

2

3

4

5

6

7

8

9

// After waits for the duration to elapse and then sends the current time

// on the returned channel.

// It is equivalent to NewTimer(d).C.

// The underlying Timer is not recovered by the garbage collector

// until the timer fires. If efficiency is a concern, use NewTimer

// instead and call Timer.Stop if the timer is no longer needed.

func After(d Duration) <-chan Time {

    return NewTimer(d).C

}

从代码可以看到,After()其实是Timer的一个语法糖。


下面通过代码演示一下三种方式的使用:

1.Ticker

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

ticker := time.NewTicker(time.Second * 1) // 运行时长

    ch := make(chan int)

    go func() {

        var x int

        for x < 10 {

            select {

            case <-ticker.C:

                x++

                fmt.Printf("%d\n", x)

            }

        }

        ticker.Stop()

        ch <- 0

    }()

    <-ch                                    // 通过通道阻塞,让任务可以执行完指定的次数。

该ticker每1秒触发一次,即ticker.C中每一秒会有一个内容加入,最后通过向ch中写入数字,让程序解除阻塞,继续执行。

2.Timer

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

timer := time.NewTimer(time.Second * 1) // timer 只能按时触发一次,可通过Reset()重置后继续触发。

    go func() {

        var x int

        for {

            select {

            case <-timer.C:

                x++

                fmt.Printf("%d,%s\n", x, time.Now().Format("2006-01-02 15:04:05"))

                if x < 10 {

                    timer.Reset(time.Second * 2)

                } else {

                    ch <- x

                }

            }

        }

    }()

    <-ch

3.After()

1

2

3

4

5

6

7

8

9

10

// 阻塞一下,等待主进程结束

    tt := time.NewTimer(time.Second * 10)

    <-tt.C

    fmt.Println("over.")

 

    <-time.After(time.Second * 4)

    fmt.Println("再等待4秒退出。tt 没有终止,打印出 over 后会看见在继续执行...")

    tt.Stop()

    <-time.After(time.Second * 2)

    fmt.Println("tt.Stop()后, tt 仍继续执行,只是关闭了 tt.C 通道。")

4.我们可以利用这些基本的方法,设计自己的定时任务管理。

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

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

type jobFunc2 func(j *job)

 

type job struct {

    jf     jobFunc2

    params map[string]interface{}

    ch     chan int

}

 

func NewJob() *job {

    return &job{

        params: make(map[string]interface{}),

        ch:     make(chan int),

    }

}

 

func (j *job) Run(t time.Duration) {

    ticker := time.NewTicker(time.Second * t)

    go func() {

        for {

            select {

            case <-ticker.C:

                j.jf(j)

            case <-j.ch:

                fmt.Println("收到结束指令")

                ticker.Stop()

                break

            }

        }

    }()

 

}

 

func main() {

    j := NewJob()

    j.jf = func(jj *job) {

        fmt.Println("定时任务执行...", time.Now().Format("15:04:05 2006-02-01"), jj.params)

    }

    j.params["p1"] = "第一个参数"

    j.params["p2"] = 100

    j.Run(1)

 

    // 阻塞一下,等待主进程结束

    tt := time.NewTimer(time.Second * 10)

    <-tt.C

    fmt.Println("over.")

 

    <-time.After(time.Second * 4)

    fmt.Println("再等待4秒退出。tt 没有终止,打印出 over 后会看见在继续执行...")

    tt.Stop()

    <-time.After(time.Second * 2)

    fmt.Println("tt.Stop()后, tt 仍继续执行,只是关闭了 tt.C 通道。")

}

部分执行结果截图:

最后补充一下,通过channel去终止任务的执行。

1

2

3

4

5

6

7

8

9

10

11

12

13

// 阻塞一下,等待主进程结束

    tt := time.NewTimer(time.Second * 10)

    <-tt.C

    fmt.Println("over.")

 

    <-time.After(time.Second * 4)

    fmt.Println("再等待4秒退出。tt 没有终止,打印出 over 后会看见在继续执行...")

    tt.Stop()

    <-time.After(time.Second * 2)

    fmt.Println("tt.Stop()后, tt 仍继续执行,只是关闭了 tt.C 通道。")

    j.ch <- 0

    <-time.After(time.Second * 2)

    fmt.Println("又等了2秒钟...这两秒钟可以看到 tt 没干活了...")


在GO语言编写中,要熟练使用 channel

以上就是go语言如何设置定时器的详细内容,更多文章请关注木庄网络博客!!

相关阅读 >>

怎么查看Go语言版本

Go语言空结构体的用法是什么

Go语言中包导入的一些问题

如何解决Go语言输出中文乱码的问题

Go语言相关工具怎么安装

Go语言是哪个公司的

Go语言中数组和切片的区别是什么?

Go语言查看环境信息的方法

Go语言适合并发的原因是什么

golang和Go语言有区别吗?

更多相关阅读请进入《Go语言》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...