42、Go语言基础 - 并发编程 - time 包与 channel 相关的函数

作者: 温新

分类: 【Go基础】

阅读: 293

时间: 2023-12-05 00:35:54

hi,我是温新

Timer 结构体

计时器类型表示单个事件。当计时器过期时,当前时间将被发送到 c 上(c 是一个只读 channel <-chan time Time,该 channel 中放入的是 Timer 结构体),除非计时器是 After() 创建的。

计时器必须使用 NewTimer()After() 创建。

其结构体源码如下:

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

NewTimer() 函数

NewTimer()time 包提供的构造函数之一。用于创建一个定时器(time.Timer),以便在未来的某个时刻触发某个操作。

函数源码

func NewTimer(d Duration) *Timer

工作原理

NewTimer 函数创建一个 Timer 实例,这个定时器将在指定的时间段(d)之后触发,触发后,可以执行相关操作。

例如,如果你创建一个定时器 t := time.NewTimer(2 * time.Second),那么定时器 t 将在 2 秒后触发。

定时器的使用

可以使用定时器的 C 属性来等待定时器触发的通道。例如:

timer := time.NewTimer(2 * time.Second)

// 等待定时器触发
<-timer.C
fmt.Println("定时器触发了!")

停止定时器

可以使用 Stop 方法来停止定时器。例如:

timer := time.NewTimer(2 * time.Second)
stopped := timer.Stop()

if stopped {
    fmt.Println("定时器已被停止")
}

NewTimer 案例

package main

import (
	"fmt"
	"time"
)

func main() {
	// 创建一个定时器,将在 5 秒后触发
	timer1 := time.NewTimer(5 * time.Second)
	fmt.Printf("%T\n", timer1)

	// 使用通道等待定时器触发
	data := <-timer1.C
	fmt.Printf("%T\n", timer1.C)
	fmt.Printf("%T\n", data)
	fmt.Println(data)
}

输出结果

*time.Timer
<-chan time.Time
time.Time
2023-10-17 22:14:17.2934755 +0800 CST m=+5.009262201

代码解释:

  • 1、导入 fmttime 包,分别用于打印输出和处理时间相关操作;
  • 2、使用 time.NewTimer(5 * time.Second) 创建一个定时器 timer,它将在 5 秒后触发;
  • 3、使用 <-timer.C 等待定时器触发。这里的 <-timer.C 会阻塞主 goroutine 直到定时器触发;
  • 4、输出结果

After() 函数

time.After 函数是 Go 语言标准库中的一个用于等待指定时间段的函数。它返回一个通道(chan time.Time),该通道会在指定的时间段过去后发送一个时间值,用于通知程序可以执行相应的操作。

函数源码

func After(d Duration) <-chan Time
  • d 是一个表示时间段的 Duration,用于指定等待的时长。
  • 返回值是一个只发送时间值的只读通道,通道会在指定的时间段过去后发送时间值。

工作原理

当你调用 time.After(d) 时,它会返回一个通道,然后等待指定的时间段 d 过去。一旦时间段 d 过去,通道将会被关闭,并发送一个时间值。可以通过从通道中读取这个时间值来知道时间段已过去,从而触发相应的操作。

After 案例

package main

import (
	"fmt"
	"time"
)

func main() {
	fmt.Println("开始执行 after 咯")
	timeout := 2 * time.Second
	<-time.After(timeout)
	fmt.Println("等待了2秒后执行此操作")
}

当执行上述代码时,程序会等待 2 秒,然后输出 "等待了2秒后执行此操作"。这是因为 <-time.After(timeout) 会等待 timeout 时间段过去后,通道将被关闭并发送时间值,从而解除阻塞,执行后续操作。

请登录后再评论