Go语言超时退出的三种实现方式总结

2023-12-05 0 561
目录
  • 1、Go语言三种方式实现超时退出
    • 1.1 context.WithTimeout/context.WithDeadline + time.After
    • 1.2 context.WithTimeout/context.WithDeadline + time.NewTimer
    • 1.3 channel + time.After/time.NewTimer

1、Go语言三种方式实现超时退出

1.1 context.WithTimeout/context.WithDeadline + time.After

// time.After(time.Duration(time.Millisecond * 700))
package main
import (
\”context\”
\”fmt\”
\”time\”
)
// Golang三种方式实现超时退出-方法1
// 场景:设定一个超时时间,若是在指定超时时间后没有返回结果,则重试
func main() {
// 经过context的WithTimeout设置一个有效时间为800毫秒的context
// 该context会在耗尽800毫秒后或者方法执行完成后结束,结束的时候会向通道ctx.Done发送信号
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Millisecond*800))
// 注意,这里要记得调用cancel(),否则即便提早执行完了,还要傻傻等到800毫秒后context才会被释放
defer cancel()
go func(ctx context.Context) {
// 发送HTTP请求
fmt.Println(\”处理请求!\”)
time.Sleep(800 * time.Millisecond)
fmt.Println(\”请求处理完毕!\”)
}(ctx)
select {
case <-ctx.Done():
fmt.Println(\”call successfully!!!\”)
return
// 这里已经设置了context的有效时间,为何还要加上这个time.After呢
// 这是由于该方法内的context是本身声明的,能够手动设置对应的超时时间,可是在大多数场景,这里的ctx是从上游一直传递过来的,
// 对于上游传递过来的context还剩多少时间,咱们是不知道的,因此这时候经过time.After设置一个本身预期的超时时间就颇有必要了
case <-time.After(time.Duration(time.Millisecond * 700)):
fmt.Println(\”timeout!!!\”)
return
}
}

程序输出

处理请求!timeout!!!

修改超时时间:

// time.After(time.Duration(time.Millisecond * 1000))
package main
import (
\”context\”
\”fmt\”
\”time\”
)
// Golang三种方式实现超时退出-方法1
// 场景:设定一个超时时间,若是在指定超时时间后没有返回结果,则重试
func main() {
// 经过context的WithTimeout设置一个有效时间为800毫秒的context
// 该context会在耗尽800毫秒后或者方法执行完成后结束,结束的时候会向通道ctx.Done发送信号
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Millisecond*800))
// 注意,这里要记得调用cancel(),否则即便提早执行完了,还要傻傻等到800毫秒后context才会被释放
defer cancel()
go func(ctx context.Context) {
// 发送HTTP请求
fmt.Println(\”处理请求!\”)
time.Sleep(800 * time.Millisecond)
fmt.Println(\”请求处理完毕!\”)
}(ctx)
select {
case <-ctx.Done():
fmt.Println(\”call successfully!!!\”)
return
// 这里已经设置了context的有效时间,为何还要加上这个time.After呢
// 这是由于该方法内的context是本身申明的,能够手动设置对应的超时时间,可是在大多数场景,这里的ctx是从上游一直传递过来的,
// 对于上游传递过来的context还剩多少时间,咱们是不知道的,因此这时候经过time.After设置一个本身预期的超时时间就颇有必要了
case <-time.After(time.Duration(time.Millisecond * 1000)):
fmt.Println(\”timeout!!!\”)
return
}
}

程序输出

处理请求!请求处理完毕!call successfully!!!

1.2 context.WithTimeout/context.WithDeadline + time.NewTimer

// time.NewTimer(time.Duration(time.Millisecond * 700))
package main
import (
\”context\”
\”fmt\”
\”time\”
)
// Golang三种方式实现超时退出-方法2
// 使用time.NewTimer
func main() {
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Millisecond*800))
defer cancel()
timer := time.NewTimer(time.Duration(time.Millisecond * 700))
go func(ctx context.Context) {
// 发送HTTP请求
fmt.Println(\”处理请求!\”)
time.Sleep(800 * time.Millisecond)
fmt.Println(\”请求处理完毕!\”)
}(ctx)
select {
case <-ctx.Done():
timer.Stop()
timer.Reset(time.Second)
fmt.Println(\”call successfully!!!\”)
return
case <-timer.C:
fmt.Println(\”timeout!!!\”)
return
}
}

程序输出

处理请求!timeout!!!

修改超时间:

// time.NewTimer(time.Duration(time.Millisecond * 1000))
package main
import (
\”context\”
\”fmt\”
\”time\”
)
// Golang三种方式实现超时退出-方法2
// 使用time.NewTimer
func main() {
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Millisecond*800))
defer cancel()
timer := time.NewTimer(time.Duration(time.Millisecond * 1000))
go func(ctx context.Context) {
// 发送HTTP请求
fmt.Println(\”处理请求!\”)
time.Sleep(800 * time.Millisecond)
fmt.Println(\”请求处理完毕!\”)
}(ctx)
select {
case <-ctx.Done():
timer.Stop()
timer.Reset(time.Second)
fmt.Println(\”call successfully!!!\”)
return
case <-timer.C:
fmt.Println(\”timeout!!!\”)
return
}
}

程序输出

处理请求!请求处理完毕!call successfully!!!

1.3 channel + time.After/time.NewTimer

// time.After(time.Duration(700 * time.Millisecond))
package main
import (
\”context\”
\”fmt\”
\”time\”
)
// Golang三种方式实现超时退出-方法3
// 使用通道
func main() {
ctx := context.Background()
done := make(chan struct{}, 1)
go func(ctx context.Context) {
// 发送HTTP请求
fmt.Println(\”处理请求!\”)
time.Sleep(800 * time.Millisecond)
fmt.Println(\”请求处理完毕!\”)
done <- struct{}{}
}(ctx)
select {
case <-done:
fmt.Println(\”call successfully!!!\”)
return
case <-time.After(time.Duration(700 * time.Millisecond)):
fmt.Println(\”timeout!!!\”)
return
}
}

程序输出

处理请求!timeout!!!

修改超时时间:

// time.After(time.Duration(1000 * time.Millisecond))
package main
import (
\”context\”
\”fmt\”
\”time\”
)
// Golang三种方式实现超时退出-方法3
// 使用通道
func main() {
ctx := context.Background()
done := make(chan struct{}, 1)
go func(ctx context.Context) {
// 发送HTTP请求
fmt.Println(\”处理请求!\”)
time.Sleep(800 * time.Millisecond)
fmt.Println(\”请求处理完毕!\”)
done <- struct{}{}
}(ctx)
select {
case <-done:
fmt.Println(\”call successfully!!!\”)
return
case <-time.After(time.Duration(1000 * time.Millisecond)):
fmt.Println(\”timeout!!!\”)
return
}
}

程序输出

处理请求!请求处理完毕!call successfully!!!

到此这篇关于Go语言超时退出的三种实现方式总结的文章就介绍到这了,更多相关Go语言超时退出内容请搜索悠久资源网以前的文章或继续浏览下面的相关文章希望大家以后多多支持悠久资源网!

您可能感兴趣的文章:

  • Golang实现超时退出的三种方式
  • Golang实现for循环运行超时后自动退出的方法
  • 深入了解Golang为什么需要超时控制
  • 深入了解Go的HttpClient超时机制
  • Go语言实现超时的三种方法实例
  • Go 中实现超时控制的方案
  • Go 协程超时控制的实现

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悠久资源 Golang Go语言超时退出的三种实现方式总结 https://www.u-9.cn/jiaoben/golang/101822.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务