这期内容当中小编将会给大家带来有关使用Golang怎么实现超时退出,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
创新互联是专业的运河网站建设公司,运河接单;提供网站建设、成都网站设计,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行运河网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!1、通过context的WithTimeout设置一个有效时间为800毫秒的context。
2、该context会在耗尽800毫秒后或者方法执行完成后结束,结束的时候会向通道ctx.Done发送信号。
3、有人可能要问,你这里已经设置了context的有效时间,为什么还要加上这个time.After呢?
这是因为该方法内的context是自己申明的,可以手动设置对应的超时时间,但是在大多数场景,这里的ctx是从上游一直传递过来的,对于上游传递过来的context还剩多少时间,我们是不知道的,所以这时候通过time.After设置一个自己预期的超时时间就很有必要了。
4、注意,这里要记得调用cancel()
,不然即使提前执行完了,还要傻傻等到800毫秒后context才会被释放。
总结
上面的超时控制是搭配使用了ctx.Done
和time.After。
Done通道负责监听context啥时候完事,如果在time.After设置的超时时间到了,你还没完事,那我就不等了,执行超时后的逻辑代码。
举一反三
那么,除了上面这种超时控制策略,还有其他的套路吗?
有,但是大同小异。
第一种:使用time.NewTimer
func AsyncCall() { ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Millisecond * 800)) defer cancel() timer := time.NewTimer(time.Duration(time.Millisecond * 900)) go func(ctx context.Context) { // 发送HTTP请求 }() select { case <-ctx.Done(): timer.Stop() timer.Reset(time.Second) fmt.Println("call successfully!!!") return case <-timer.C: fmt.Println("timeout!!!") return } }
这里的主要区别是将time.After换成了time.NewTimer
,也是同样的思路如果接口调用提前完成,则监听到Done信号,然后关闭定时器。
否则的话,会在指定的timer即900毫秒后执行超时后的业务逻辑。
第二种:使用通道
func AsyncCall() { ctx := context.Background() done := make(chan struct{}, 1) go func(ctx context.Context) { // 发送HTTP请求 done <- struct{}{} }() select { case <-done: fmt.Println("call successfully!!!") return case <-time.After(time.Duration(800 * time.Millisecond)): fmt.Println("timeout!!!") return } }
1、这里主要利用通道可以在协程之间通信的特点,当调用成功后,向done通道发送信号。
2、监听Done信号,如果在time.After超时时间之前接收到,则正常返回,否则走向time.After的超时逻辑,执行超时逻辑代码。
3、这里使用的是通道和time.After组合,也可以使用通道和time.NewTimer组合。
上述就是小编为大家分享的使用Golang怎么实现超时退出了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注创新互联成都网站设计公司行业资讯频道。
另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。