time包中的通道相关函数
# time包中的通道相关函数
- https://golang.google.cn/pkg/time/
主要就是定时器,标准库中的Timer
让用户可以定义自己的超时逻辑,尤其是在应对select
处理多个channel
的超时、单channel
读写的超时等情形时尤为方便.
Timer
是一次性的时间触发事件,这点与Ticker
不同,Ticker
是按一定时间间隔持续触发时间事件.
Timer
常见的创建方式
t: = time.NewTimer(d)
t: = time.AfterFunc(d,f)
c: = time.After(d)
1
2
3
2
3
虽然说创建方式不同,但是原理相同的.
Timmer
有3个要素
定时时间: 就是那个
d
触发动作: 就是那个
f
时间
channel
: 也就是t.C
# 一、time.NewTimer()
NewTimer()
创建一个新的计时器,该计时器将在其通道上至少持续d
之后发送当前时间.
NewTimer
源码
// NewTimer creates a new Timer that will send
// the current time on its channel after at least duration d.
func NewTimer(d Duration) *Timer {
c := make(chan Time, 1)
t := &Timer{
C: c,
r: runtimeTimer{
when: when(d),
f: sendTime,
arg: c,
},
}
startTimer(&t.r)
return t
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
通过源码可以看出,首先创建一个channel
,关联的类型为Time
,然后创建了一个Timer
并返回
- 用于在指定的
Duration
类型时间后调用函数或计算表达式. - 如果只是想指定时间之后执行,使用
time.Sleep()
- 使用
NewTimer()
,可以返回的Timer
类型在计时器到期之前,取消该计时器 - 直到使用
<-timer.C
发送一个值,该计时器才会过期.
示例代码
package main
import (
"fmt"
"time"
)
func main() {
/*
1.func NewTimer(d Duration) *Timer
创建一个计时器,时间以后触发
*/
timer := time.NewTimer(3 * time.Second)
fmt.Printf("%T\n", timer) //*time.Timer
fmt.Println(time.Now()) // 2022-11-25 12:06:50.9444009 +0800 CST m=+0.002697901
//此处等待`channel`中的数值,会阻塞3秒
ch1 := timer.C
fmt.Println(<-ch1) // 2022-11-25 12:06:53.9565868 +0800 CST m=+3.014883801
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
执行结果
# 二、timer.Stop
# 计时器停止
timer.Stop
源码
// Stop prevents the Timer from firing.
// It returns true if the call stops the timer, false if the timer has already
// expired or been stopped.
// Stop does not close the channel, to prevent a read from the channel succeeding
// incorrectly.
//
// To ensure the channel is empty after a call to Stop, check the
// return value and drain the channel.
// For example, assuming the program has not received from t.C already:
//
// if !t.Stop() {
// <-t.C
// }
//
// This cannot be done concurrent to other receives from the Timer's
// channel or other calls to the Timer's Stop method.
//
// For a timer created with AfterFunc(d, f), if t.Stop returns false, then the timer
// has already expired and the function f has been started in its own goroutine;
// Stop does not wait for f to complete before returning.
// If the caller needs to know whether f is completed, it must coordinate
// with f explicitly.
func (t *Timer) Stop() bool {
if t.r.f == nil {
panic("time: Stop called on uninitialized Timer")
}
return stopTimer(&t.r)
}
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
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
示例代码
package main
import (
"fmt"
"time"
)
func main() {
/*
1.func NewTimer(d Duration) *Timer
创建一个计时器,时间以后触发
*/
//新建一个计时器
timer2 := time.NewTimer(5 * time.Second)
//开始`goroutine`,来处理触发后的事件
go func() {
<-timer2.C
fmt.Println("Timer 2 结束了...开始...")
}()
time.Sleep(3 * time.Second)
flag := timer2.Stop()
if flag {
fmt.Println("Timer2 停止了...")
}
}
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
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
执行结果
# 三、time.After()
在等待持续时间之后,然后在返回的通道上发送当前时间.它相当NewTimer(d).C
.在计时器触发之前,垃圾收集器不会恢复底层计时器,如果效率有问题,使用NewTimer
代替,并调用Timer
.如果不再需要计时器,请停止.
源码
// 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
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
示例代码
package main
import (
"fmt"
"time"
)
func main() {
/*
2.func After(d Duration) <-chan Time
返回一个通道: chan,存储的是d时间间隔之后的当前时间
相当于: return NewTimer(d).C
*/
ch := time.After(3 * time.Second)
fmt.Printf("%T\n", ch) // <-chan time.Time
fmt.Println(time.Now())
time1 := <-ch
fmt.Println(time1)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
执行结果
上次更新: 2024/04/09, 16:48:42
- 01
- AWS NAT-NetWork-Firwalld配置(一)04-09
- 02
- AWS NAT-NetWork-Firwalld配置(二)04-09
- 03
- kubernetes部署minio对象存储01-18