先上代码:

package mainimport ("fmt""time"
)func main() {//closeChannel()c := make(chan int)timeout := time.After(time.Second * 2) //t1 := time.NewTimer(time.Second * 3)   // 效果相同 只执行一次var i intgo func() {for {select {case <-c:fmt.Println("channel sign")returncase <-t1.C:      // 代码段2fmt.Println("3s定时任务")case <-timeout:   // 代码段1i++fmt.Println(i, "2s定时输出")case <-time.After(time.Second * 4):    // 代码段3fmt.Println("4s timeout。。。。") default:                               // 代码段4fmt.Println("default")time.Sleep(time.Second * 1)}}}()time.Sleep(time.Second * 6)close(c)time.Sleep(time.Second * 2)fmt.Println("main退出")
}

主要有以上4点是我们平时遇到的。

首先遇到的问题是:

如上的代码情况下, 代码段3处的case 永远不执行, 无论main进程执行多久。这是为什么呢?

首先我们分析为啥不执行代码段3, 而是程序一直执行的是default.  由此我们判断:

case <- time.After(time.Second)  :

是本次监听动作的超时时间, 意思就说,只有在本次select 操作中会有效, 再次select 又会重新开始计时(从当前时间+4秒后), 但是有default ,那case 超时操作,肯定执行不到了。

那么问题就简单了我们预先定义了计时操作:

case <- timeout:

在goroutine开始前, 我们记录了时间,在此时间3s之后进行操作。相当于定时任务, 并且只执行一次。 代码段1和代码段2 实现的结果都相同

针对以上问题解决后,我写了一个小案例:

package mainimport ("fmt""time"
)//发送者
func sender(c chan int) {for i := 0; i < 100; i++ {c <- iif i >= 5 {time.Sleep(time.Second * 7)} else {time.Sleep(time.Second)}}
}func main() {c := make(chan int)go sender(c)timeout := time.After(time.Second * 3)for {select {case d := <-c:fmt.Println(d)case <-timeout:fmt.Println("这是定时操作任务 >>>>>")case dd := <-time.After(time.Second * 3):fmt.Println(dd, "这是超时*****")}fmt.Println("for end")}
}

执行结果:

要注意的是,虽然执行到i == 6时, 堵塞了,并且执行了超时操作, 但是下次select 依旧去除的是6

因为通道中已经发送了6,如果未取出,程序堵塞。

golang time.After 超时使用理解相关推荐

  1. Golang的反射reflect深入理解和示例

    [TOC] Golang的反射reflect深入理解和示例 [记录于2018年2月] 编程语言中反射的概念 在计算机科学领域,反射是指一类应用,它们能够自描述和自控制.也就是说,这类应用通过采用某种机 ...

  2. golang net/http 超时机制完全手册

    目录 SetDeadline 服务器端超时设置 客户端超时设置 Cancel 和 Context 英文原始出处: The complete guide to Go net/http timeouts, ...

  3. golang goroutine实现_Go goroutine理解

    Go语言最大的特色就是从语言层面支持并发(Goroutine),Goroutine是Go中最基本的执行单元.事实上每一个Go程序至少有一个Goroutine:主Goroutine.当程序启动时,它会自 ...

  4. golang协程介绍和理解

    1.介绍协程前先需要了解进程和线程 进程:程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位. 线程:进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基 ...

  5. golang 切片 接口_如何理解Golang中的接口?

    个人认为,要理解 Go 的接口,一定先了解下鸭子模型. 鸭子模型 那什么鸭子模型? 鸭子模型的解释,通常会用了一个非常有趣的例子,一个东西究竟是不是鸭子,取决于它的能力.游泳起来像鸭子.叫起来也像鸭子 ...

  6. go 语言 proxy.golang.org timeout 超时解决

    报错信息 报错包含proxy.golang.org timeout 以及下列信息 Finding targets go: github.com/armon/go-socks5@v0.0.0-20160 ...

  7. go语言安装google.golang.org/grpc 超时问题

    官方安装命令: go get google.golang.org/grpc 是安装不起的,会报: package google.golang.org/grpc: unrecognized import ...

  8. RTT时钟管理篇——RTT定时器超时判断理解

  9. Golang中的runtime.Caller理解

    func Caller(skip int) (pc uintptr, file string, line int, ok bool) 参数:skip是要提升的堆栈帧数,0-当前函数,1-上一层函数,. ...

最新文章

  1. SharePoint2010沙盒解决方案基础开发——关于TreeView树形控件读取列表数据(树形导航)的webpart开发及问题...
  2. 定时分量和直流分量_直流电机效率测试的计算与纹波因数及波形因数的计算
  3. 电脑磁盘空间不足怎么办_IT干货 丨 电脑C盘存储空间不足怎么办?
  4. Java 异常java.lang.IllegalArgumentException: Illegal group reference
  5. Eclipse常用快捷键、常用设置、常见问题等
  6. 使用 Navicat Premium 将 sql server 的数据库迁移到 mysql 的数据库中
  7. 用forif循环测量minst0-6的特征迭代次数曲线
  8. LAMP架构(七)配置防盗链,访问控制
  9. C 结构体嵌套一级指针 二级指针 动态分配内存
  10. 大数据场景中语言虚拟机的应用和挑战
  11. php 各种排序算法,PHP四种常见排序算法
  12. 请不要重复犯我在学习Python和Linux系统上的错误
  13. 网管工具-snmpset使用总结
  14. STM32 自定义串口协议
  15. TVS 瞬态抑制二极管指南
  16. 如何用计算机名查看共享打印机,如何查找网络共享打印机
  17. 【折腾系列—All In One主机】4、 iKuai软路由安装及配置
  18. Altium Designer之4层板基本规则设置
  19. 计算机网络基础交换机的基本配置实验报告,计算机网络基础实验报告
  20. html战旗游戏,战棋页游-策略类战棋网页游戏推荐

热门文章

  1. C 家族程序设计语言发展史
  2. Openstack Nova 源码分析 — RPC 远程调用过程
  3. Ditto剪贴板增强工具 ,方便复制粘贴多条历史记录
  4. altium designer寻找未连接飞线
  5. 79-定义不同颜色字体
  6. 学会使用函数式编程的程序员(第2部分)
  7. OAuth2.0的理解基础
  8. MQ对比之RabbitMQ Redis
  9. LINQ教程二:LINQ操作语法
  10. main函数带参数C程序设计模板