golang 中常用的超时控制的方案示例

go 中,我们很容易就可以实现超时控制,今天分享2种解决方案:

  • 1.select + time.After
  • 2.select + context

其实两种方案中,我们都是通过 channel 来控制的,在方案1中,对于 time.After, 通过返回一个只读 <- chan Time 实现,而 context 中,则通过 context.Done() 实现,通过返回 <- chan struct{} 信号实现,

下面看看函数签名:
time.After
可以看到,只需要传入一个时间的duration即可。

// go1.19/src/time/sleep.go
func After(d Duration) <-chan Time {
return NewTimer(d).C
}

context.Done
这其实是通过实现 context接口的 timeCtx

接下来看看超时控制的相关代码实现。

1.select + time.After

package main
import (
"context"
"fmt"
"time"
)
func main() {
fmt.Printf("[%s] start...\n", time.Now().Format(time.RFC3339))
taskCh := make(chan int)
go func() {
time.Sleep(5*time.Second)
taskCh <- 1
}()
select {
case data := <- taskCh:
fmt.Println(data)
case <- time.After(time.Second):
fmt.Println("timeout!")
}
fmt.Printf("[%s] end...\n", time.Now().Format(time.RFC3339))
}

我们通过实现一个耗时的task实现任务耗时,在time.After中传入1s的超时,到1s时,该case先收到信号,从而结束整个执行。

2.select + context

package main
import (
"context"
"fmt"
"time"
)
func main() {
fmt.Printf("[%s] start...\n", time.Now().Format(time.RFC3339))
ctx, cancel := context.WithTimeout(context.Background(), 3 * time.Second)
defer cancel()
taskCh := make(chan int)
go func() {
time.Sleep(5*time.Second)
taskCh <- 1
}()
select {
case data := <- taskCh:
fmt.Println(data)
case <- ctx.Done():
fmt.Println("timeout!")
}
fmt.Printf("[%s] end...\n", time.Now().Format(time.RFC3339))
}

类似于上一个方案,我们只是在context中传入3s的超时时长,到了时间后,就会收到 ctx.Done(),进而结束执行。

posted on   进击的davis  阅读(690)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
历史上的今天:
2021-04-21 Django项目部署 + docker

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示