通道计时器,处理事件的新思路

简介: 通道计时器,处理事件的新思路

概述

在 Go 语言中,通道(Channel)和计时器(Timer)是两个强大的并发工具,它们的结合使用可以优雅地处理各种事件。

本文将探讨如何使用通道响应计时器的事件,并通过详实的示例代码展示在不同场景下的应用。


 

1. 通道与计时器基础

1.1 通道的基本概念

通道是 Go 语言中并发编程的核心机制之一,用于在不同的 goroutine 之间传递数据。

make 函数创建


ch := make(chan int)

1.2 计时器的基本概念

计时器是 Go 语言中用于定时执行任务的工具,通过 time 包提供。

创建一个计时器


timer := time.NewTimer(time.Second)


 

2. 使用通道接收计时器事件

2.

package main
import (  "fmt"  "time")
func main() {  ch := make(chan string)
  go func() {    time.Sleep(2 * time.Second)    ch <- "事件发生"  }()
  select {  case msg := <-ch:    fmt.Println(msg)  case <-time.After(3 * time.Second):    fmt.Println("超时,未接收到事件")  }}

在上面示例中,创建了一个通道 ch,并在一个新的 goroutine 中等待 2 秒后往通道发送消息。

select 语句监听通道的消息和计时器的事件,哪个先到达就执行哪个。

2.2 计时器复用


package main
import (  "fmt"  "time")
func main() {  ch := make(chan string)  timer := time.NewTimer(2 * time.Second)
  go func() {    time.Sleep(1 * time.Second)    ch <- "事件发生"  }()
  select {  case msg := <-ch:    fmt.Println(msg)  case <-timer.C:    fmt.Println("超时,未接收到事件")  }}

在上述示例中,创建了一个计时器 timer,它设置为 2 秒。

同样,用 select 监听通道和计时器的事件,但这次用 timer.C 直接监听计时器的事件。


 

3. 使用通道控制计时器

3.1 通道关闭触发计时器


package main
import (  "fmt"  "time")
func main() {  ch := make(chan string)  timer := time.NewTimer(3 * time.Second)
  go func() {    time.Sleep(2 * time.Second)    close(ch)  }()
  select {    case msg, ok := <-ch:    if !ok {      fmt.Println("通道已关闭")      break    }    fmt.Println(msg)    case <-timer.C:    fmt.Println("超时,未接收到事件")  }}

在上面示例中,在 goroutine 中等待 2 秒后关闭通道。

用检查 ok 的值,可以知道通道是否已关闭,从而避免读取已关闭通道引发的异常。

3.

package main
import (  "fmt"  "time")
func main() {  ch := make(chan string, 1)  timer := time.NewTimer(3 * time.Second)
  go func() {    time.Sleep(2 * time.Second)    ch <- "事件发生"  }()
  select {  case msg := <-ch:    fmt.Println(msg)  case <-timer.C:    fmt.Println("超时,未接收到事件")  }}

在这个示例中,将通道 ch 设置为带缓冲的通道,容量为 1。

这样,即使计时器事件先到,通道也能接收到消息,因为有缓冲空间。


 

4. 实战场景

4.1

package main
import (  "fmt"  "time")
func main() {  ticker := time.NewTicker(1 * time.Second)  defer ticker.Stop()
  for {    select {    case <-ticker.C:      fmt.Println("定时任务执行")    }  }}

在上述示例中,使用 time.NewTicker 创建了一个定时器,并通过 select 监听定时器的事件。

在每次定时器触发时,执行相应的周期性任务。

4

package main
import (  "fmt"  "time")
func main() {  ch := make(chan string)
  select {  case msg := <-ch:    fmt.Println(msg)    case <-time.After(3 * time.Second):    fmt.Println("超时,未接收到事件")  }}

在上面示例中,用 time.After 函数创建一个计时器,当超时时,会向通道发送当前时间。

select 监听通道和计时器的事件,实现超时处理。


 

5. 总结

通过本文的讲解和示例代码,了解了如何使用通道响应计时器的事件。

通道和计时器的结合使用能够优雅地处理各种并发场景,包括超时处理、周期性任务等。

当然,使用通道来响应计时器也有一些注意事项:

通道操作需要确保同步正确,避免数据竞争

需要确保不会漏掉计时器的事件

重置计时器时要小心计时和通道处理的时序关系

在使用 Go 语言的并发编程特性时,记住思考通道、同步和事件顺序,这会帮助你编写出高质量和正确的 Go 程序。

目录
相关文章
|
8月前
|
编译器 C++ 开发者
QT基础【7-跨进程发送信号】
QT基础【7-跨进程发送信号】
|
2月前
|
iOS开发 MacOS
简单而高效的计时器
【10月更文挑战第14天】
|
4月前
|
前端开发 JavaScript
前端基础(十三)_定时器(间歇定时器、延迟定时器)
本文介绍了JavaScript中定时器的使用,包括`setTimeout`和`setInterval`两种类型。`setTimeout`是实现延迟执行,即等待一定时间后执行一次指定的函数;而`setInterval`是实现间歇执行,即每隔一定时间就执行一次指定的函数。文章还介绍了如何使用`clearTimeout`和`clearInterval`来取消定时器的执行,并通过示例代码展示了定时器的创建和取消。
166 4
前端基础(十三)_定时器(间歇定时器、延迟定时器)
|
6月前
|
物联网 UED 智能硬件
无线模块空中唤醒技术原理详解
空中唤醒(Wake on Radio, WOR)技术**降低了设备功耗,通过休眠和接收模式切换实现。设备接收到特殊前导码时唤醒,未接收到数据则返回休眠。配置精确的唤醒和休眠时间确保响应及时且节能。不仅用于数据接收,还能结合智能操作,如空中轨迹唤醒,提升用户体验。广泛应用于物联网和智能家居,随着技术发展,其潜力和应用将更加广泛。
133 0
|
8月前
|
传感器 人工智能 算法
掌握C++中的状态-事件回调矩阵:打造强大的有限状态机
掌握C++中的状态-事件回调矩阵:打造强大的有限状态机
181 0
|
前端开发
Electron 渲染进程与渲染进程之间的实时通信 (实时触发及接收消息)
Electron 渲染进程与渲染进程之间的实时通信 (实时触发及接收消息)
MOTOROLA 30-W2960B01A 增加了对消息信号中断
MOTOROLA 30-W2960B01A 增加了对消息信号中断
97 0
MOTOROLA 30-W2960B01A 增加了对消息信号中断
|
存储 缓存 小程序
如何实现游戏中的在线计时器和离线计时器
本文包含了游戏中两种计时器的实现原理和实现方法,皆在帮助你彻底的搞懂游戏开发中的计时器。 如果你没有任何的游戏开发经验,欢迎观看我的“人人都能做游戏”系列视频教程,它会手把手的教你做出自己的第一个小游戏。 在游戏中经常会有需要倒计时的需求,例如倒计时 10 分钟可以获得 1 点体力,倒计时 1 小时后可以开启一个宝箱,或者是根据游戏的计时获得奖励等等。
322 0
|
传感器 机器学习/深度学习 人工智能
【控制】事件触发机制下带领导者的多智能体最优控制附matlab代码
【控制】事件触发机制下带领导者的多智能体最优控制附matlab代码

热门文章

最新文章

下一篇
开通oss服务