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

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

概述

在 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 程序。

目录
相关文章
|
API
最新!中国天气网api接口调用,key获取方式,数据请求秘钥获取,城市id获取方法
最新!中国天气网api接口调用,key获取方式,数据请求秘钥获取,城市id获取方法
6901 1
最新!中国天气网api接口调用,key获取方式,数据请求秘钥获取,城市id获取方法
|
分布式计算 关系型数据库 BI
加速查询MaxCompute再对接FBI(帆软)的完整链路来啦!
本文旨在分享使用交互式分析查询MaxCompute数据,再对接FBI的完整链路,快速搭建大数据生态完整链路。
4857 0
hbuilderX 云打包 APP
hbuilderX 云打包 APP
460 0
|
API 数据安全/隐私保护 开发者
​收不到验证码邮件该怎么办?
在日常生活中,收不到邮箱验证码会带来不便。解决方法包括:检查垃圾邮件文件夹并调整过滤设置;确认邮箱地址无误或使用备用邮箱;检查邮箱存储空间并设置自动清理;了解邮件服务提供商状态或尝试其他服务。使用AOKSend可确保验证码邮件顺利送达:注册账户,获取API密钥,配置SMTP设置,并利用分析工具优化邮件发送策略。遵循这些建议,能有效解决收不到验证码的问题。
|
XML 存储 Web App开发
技术笔记:UserData使用总结
技术笔记:UserData使用总结
555 0
|
SQL 缓存 监控
MySQL慢查询:慢SQL定位、日志分析与优化方案,真心不错!
MySQL慢查询:慢SQL定位、日志分析与优化方案,真心不错!
MySQL慢查询:慢SQL定位、日志分析与优化方案,真心不错!
|
弹性计算 大数据 测试技术
2024新版阿里云服务器收费价格表汇总:一键查看阿里云服务器最新报价!
今天,我们就来详细解析一下阿里云新版云服务器的收费价格,帮助大家更好地选择适合自己的云服务器。2024年阿里云服务器租用费用价格表更新,云服务器ECS经济型e实例2核2G、3M固定带宽99元一年、ECS u1实例2核4G、5M固定带宽、80G ESSD Entry盘优惠价格199元一年,轻量应用服务器2核2G3M带宽轻量服务器一年61元、2核4G4M带宽轻量服务器一年165元12个月、2核4G服务器30元3个月,幻兽帕鲁4核16G和8核32G服务器配置,云服务器ECS可以选择经济型e实例、通用算力u1实例、ECS计算型c7、通用型g7、c8i、g8i等企业级实例规格。今天分享阿里云服务器租用费
6471 1
|
Linux 测试技术
Redhat7.2配置免费yum源(简单五步轻松搞定)
步骤一:清除redhat原有的yum源 步骤二:下载163的yum包 wget http://mirrors.163.com/centos/7.2.1511/os/x86_64/Packages/yum-3.
2744 0