乐趣区

关于后端:掌握-Go-的计时器

简介

定时器是任何编程语言的重要工具,它容许开发人员在特定工夫距离安顿工作或执行代码。在 Go 中,定时器是通过 time 包实现的,该包提供了一系列性能来创立、启动、进行和无效解决定时器。咱们将摸索 Go 中定时器的弱小性能,并通过代码示例演示如何在应用程序中应用定时器。

创立计时器

要在 Go 中创立一个定时器,咱们能够应用 time.NewTimer() 函数,该函数将持续时间作为参数。上面是一个示例:

func CreateTimer() {timer := time.NewTimer(2 * time.Second)
    fmt.Println("Timer created.")

    <-timer.C // 阻塞
    fmt.Println("Timer expired.")
}

在上述代码片段中,咱们应用 time.NewTimer() 创立了一个持续时间为 2 秒的新定时器。<-timer.C 语句会阻塞执行,直到定时器过期。定时器到期后,”Timer expired.”(定时器已过期)信息将打印到控制台。

进行计时器

在某些状况下,您可能想在定时器到期前进行它。为此,您能够应用定时器对象的 Stop() 办法。让咱们批改之前的示例,退出定时器进行性能:

func StopTimer() {timer := time.NewTimer(2 * time.Second)
    fmt.Println("Timer created.")

    go func() {
        <-timer.C
        fmt.Println("Timer expired.")
    }()

    time.Sleep(1 * time.Second)
    stopped := timer.Stop()
    if stopped {fmt.Println("Timer stopped.")
    } else {fmt.Println("Timer has already expired.")
    }
}

在更新后的代码中,咱们创立了一个 goroutine 来解决定时器过期,这样就能够在定时器过期前进行它。咱们应用 time.Sleep() 函数来模仿在尝试进行计时器之前正在进行的一些工作。最初,咱们调用 timer.Stop() 进行定时器。如果定时器已过期,timer.Stop() 返回 false,并打印 “ 定时器已过期 ”。否则,咱们将打印 “ 定时器已进行 ”。

重置计时器

Go 还提供了重置流动定时器的办法。通过 Reset() 办法,您能够更改流动定时器的持续时间,从新开始倒计时。上面是一个示例:

func ResetTimer() {timer := time.NewTimer(10 * time.Second)
    fmt.Printf("time: %d, Timer created.\n", time.Now().Unix())

    time.Sleep(2 * time.Second)
    reset := timer.Reset(3 * time.Second)
    if reset {fmt.Printf("time: %d, Timer reset.\n", time.Now().Unix())
    } else {fmt.Printf("time: %d, Timer has already expired.\n", time.Now().Unix())
    }
    <-timer.C // 阻塞
    fmt.Printf("time: %d, Timer expired again.\n", time.Now().Unix())
}

输入为:

time: 1695183503, Timer created.
time: 1695183505, Timer reset.
time: 1695183508, Timer expired again.

在上述代码中,咱们创立了一个持续时间为 10 秒的计时器。应用 time.Sleep() 期待 2 秒后,咱们调用 timer.Reset(),新的持续时间为 3 秒。如果定时器尚未过期,则重置操作胜利,咱们将打印 “ 定时器重置 ”。否则,进入到 <-timer.C 阻塞阶段,而后打印 咱们将打印 “Timer expired again.”。

重置定时器与进行定时器

理解重置定时器和应用 Stop() 进行定时器之间的区别十分重要。

func CompareResetAndStop() {timer := time.NewTimer(5 * time.Second)
    fmt.Printf("time: %d, Timer created.\n", time.Now().Unix())

    go func() {
        <-timer.C
        fmt.Printf("time: %d, Timer expired.\n", time.Now().Unix())
    }()

    time.Sleep(2 * time.Second)
    timer.Reset(3 * time.Second)
    fmt.Printf("time: %d, Timer reset.\n", time.Now().Unix())

    time.Sleep(2 * time.Second)
    timer.Stop()
    fmt.Printf("time: %d, Timer stopped.\n", time.Now().Unix())
}

输入为:

time: 1695183802, Timer created.
time: 1695183804, Timer reset.
time: 1695183806, Timer stopped.

在本例中,咱们创立了一个持续时间为 5 秒的计时器。2 秒后,咱们应用 timer.Reset() 将计时器重置为 3 秒。之后,再过 2 秒,咱们应用 timer.Stop() 进行计时器。重置定时器会扭转其持续时间并从新开始倒计时,而进行定时器则会立刻进行执行,无论残余持续时间多长。

带 Ticker 的计时器

Go 提供了一种 Ticker 类型,它是一种专门的定时器,可在指定的工夫距离内反复触发。定时器可用于定期执行工作。

func Tick() {ticker := time.NewTicker(1 * time.Second)
    defer ticker.Stop()

    go func() {
        for range ticker.C {fmt.Printf("time: %d, Ticker ticked!\n", time.Now().Unix())
        }
    }()

    time.Sleep(5 * time.Second)
}

在本例中,咱们应用 time.NewTicker() 创立了一个持续时间为 1 秒的 Ticker。而后,咱们启动一个 goroutine,从 ticker.C channel 接管值,每当滴答声响起时,goroutine 就会收回一个值。在 goroutine 中,每次接管到一个 tick 时,咱们都会打印 “Ticker ticked!”。调用 time.Sleep() 能够让滴答滴答运行 5 秒钟,而后退出程序。

应用 Select 的超时

Go 的 select 语句容许在多个通道上执行非阻塞操作。这能够用来应用计时器实现超时。

func TimeOut() {ch := make(chan string)

    go func() {time.Sleep(2 * time.Second)
        ch <- "Operation completed."
    }()

    select {
    case msg := <-ch:
        fmt.Println(msg)
    case <-time.After(1 * time.Second):
        fmt.Println("Timeout reached.")
    }
}

在本例中,咱们创立了一个 channel ch,并启动一个 goroutine 来模仿耗时 2 秒的操作。咱们应用 select 语句从 ch 接管信息,或应用 time.After() 期待超时。如果操作在 1 秒内实现,则打印消息。否则,将执行超时状况,并打印 “Timeout reached.”。

本文由 mdnice 多平台公布

退出移动版