Go語言超時退出的三種實現(xiàn)方式總結(jié)
更新時間:2023年06月18日 09:38:35 作者:242030
這篇文章主要為大家詳細(xì)介紹了Go語言中超時退出的三種實現(xiàn)方式,文中的示例代碼簡潔易懂,對我們深入了解Go語言有一定的幫助,需要的可以了解一下
1、Go語言三種方式實現(xiàn)超時退出
1.1 context.WithTimeout/context.WithDeadline + time.After
// time.After(time.Duration(time.Millisecond * 700))
package main
import (
"context"
"fmt"
"time"
)
// Golang三種方式實現(xiàn)超時退出-方法1
// 場景:設(shè)定一個超時時間,若是在指定超時時間后沒有返回結(jié)果,則重試
func main() {
// 經(jīng)過context的WithTimeout設(shè)置一個有效時間為800毫秒的context
// 該context會在耗盡800毫秒后或者方法執(zhí)行完成后結(jié)束,結(jié)束的時候會向通道ctx.Done發(fā)送信號
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Millisecond*800))
// 注意,這里要記得調(diào)用cancel(),否則即便提早執(zhí)行完了,還要傻傻等到800毫秒后context才會被釋放
defer cancel()
go func(ctx context.Context) {
// 發(fā)送HTTP請求
fmt.Println("處理請求!")
time.Sleep(800 * time.Millisecond)
fmt.Println("請求處理完畢!")
}(ctx)
select {
case <-ctx.Done():
fmt.Println("call successfully!!!")
return
// 這里已經(jīng)設(shè)置了context的有效時間,為何還要加上這個time.After呢
// 這是由于該方法內(nèi)的context是本身聲明的,能夠手動設(shè)置對應(yīng)的超時時間,可是在大多數(shù)場景,這里的ctx是從上游一直傳遞過來的,
// 對于上游傳遞過來的context還剩多少時間,咱們是不知道的,因此這時候經(jīng)過time.After設(shè)置一個本身預(yù)期的超時時間就頗有必要了
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三種方式實現(xiàn)超時退出-方法1
// 場景:設(shè)定一個超時時間,若是在指定超時時間后沒有返回結(jié)果,則重試
func main() {
// 經(jīng)過context的WithTimeout設(shè)置一個有效時間為800毫秒的context
// 該context會在耗盡800毫秒后或者方法執(zhí)行完成后結(jié)束,結(jié)束的時候會向通道ctx.Done發(fā)送信號
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Millisecond*800))
// 注意,這里要記得調(diào)用cancel(),否則即便提早執(zhí)行完了,還要傻傻等到800毫秒后context才會被釋放
defer cancel()
go func(ctx context.Context) {
// 發(fā)送HTTP請求
fmt.Println("處理請求!")
time.Sleep(800 * time.Millisecond)
fmt.Println("請求處理完畢!")
}(ctx)
select {
case <-ctx.Done():
fmt.Println("call successfully!!!")
return
// 這里已經(jīng)設(shè)置了context的有效時間,為何還要加上這個time.After呢
// 這是由于該方法內(nèi)的context是本身申明的,能夠手動設(shè)置對應(yīng)的超時時間,可是在大多數(shù)場景,這里的ctx是從上游一直傳遞過來的,
// 對于上游傳遞過來的context還剩多少時間,咱們是不知道的,因此這時候經(jīng)過time.After設(shè)置一個本身預(yù)期的超時時間就頗有必要了
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三種方式實現(xiàn)超時退出-方法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) {
// 發(fā)送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三種方式實現(xiàn)超時退出-方法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) {
// 發(fā)送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三種方式實現(xiàn)超時退出-方法3
// 使用通道
func main() {
ctx := context.Background()
done := make(chan struct{}, 1)
go func(ctx context.Context) {
// 發(fā)送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三種方式實現(xiàn)超時退出-方法3
// 使用通道
func main() {
ctx := context.Background()
done := make(chan struct{}, 1)
go func(ctx context.Context) {
// 發(fā)送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!!!
到此這篇關(guān)于Go語言超時退出的三種實現(xiàn)方式總結(jié)的文章就介紹到這了,更多相關(guān)Go語言超時退出內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在Linux系統(tǒng)中安裝Go語言的詳細(xì)教程
這篇文章主要介紹了在Linux系統(tǒng)中安裝Go語言的詳細(xì)教程,由于國內(nèi)很多人對谷歌的盲目追捧,導(dǎo)致Go語言在國內(nèi)的人氣遠(yuǎn)超國外...需要的朋友可以參考下2015-06-06

