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()
,进而结束执行。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
2021-04-21 Django项目部署 + docker