Go語(yǔ)言超時(shí)退出的三種實(shí)現(xiàn)方式總結(jié)
1、Go語(yǔ)言三種方式實(shí)現(xiàn)超時(shí)退出
1.1 context.WithTimeout/context.WithDeadline + time.After
// time.After(time.Duration(time.Millisecond * 700))
package main
import (
"context"
"fmt"
"time"
)
// Golang三種方式實(shí)現(xiàn)超時(shí)退出-方法1
// 場(chǎng)景:設(shè)定一個(gè)超時(shí)時(shí)間,若是在指定超時(shí)時(shí)間后沒有返回結(jié)果,則重試
func main() {
// 經(jīng)過(guò)context的WithTimeout設(shè)置一個(gè)有效時(shí)間為800毫秒的context
// 該context會(huì)在耗盡800毫秒后或者方法執(zhí)行完成后結(jié)束,結(jié)束的時(shí)候會(huì)向通道ctx.Done發(fā)送信號(hào)
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Millisecond*800))
// 注意,這里要記得調(diào)用cancel(),否則即便提早執(zhí)行完了,還要傻傻等到800毫秒后context才會(huì)被釋放
defer cancel()
go func(ctx context.Context) {
// 發(fā)送HTTP請(qǐng)求
fmt.Println("處理請(qǐng)求!")
time.Sleep(800 * time.Millisecond)
fmt.Println("請(qǐng)求處理完畢!")
}(ctx)
select {
case <-ctx.Done():
fmt.Println("call successfully!!!")
return
// 這里已經(jīng)設(shè)置了context的有效時(shí)間,為何還要加上這個(gè)time.After呢
// 這是由于該方法內(nèi)的context是本身聲明的,能夠手動(dòng)設(shè)置對(duì)應(yīng)的超時(shí)時(shí)間,可是在大多數(shù)場(chǎng)景,這里的ctx是從上游一直傳遞過(guò)來(lái)的,
// 對(duì)于上游傳遞過(guò)來(lái)的context還剩多少時(shí)間,咱們是不知道的,因此這時(shí)候經(jīng)過(guò)time.After設(shè)置一個(gè)本身預(yù)期的超時(shí)時(shí)間就頗有必要了
case <-time.After(time.Duration(time.Millisecond * 700)):
fmt.Println("timeout!!!")
return
}
}程序輸出
處理請(qǐng)求!
timeout!!!
修改超時(shí)時(shí)間:
// time.After(time.Duration(time.Millisecond * 1000))
package main
import (
"context"
"fmt"
"time"
)
// Golang三種方式實(shí)現(xiàn)超時(shí)退出-方法1
// 場(chǎng)景:設(shè)定一個(gè)超時(shí)時(shí)間,若是在指定超時(shí)時(shí)間后沒有返回結(jié)果,則重試
func main() {
// 經(jīng)過(guò)context的WithTimeout設(shè)置一個(gè)有效時(shí)間為800毫秒的context
// 該context會(huì)在耗盡800毫秒后或者方法執(zhí)行完成后結(jié)束,結(jié)束的時(shí)候會(huì)向通道ctx.Done發(fā)送信號(hào)
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Millisecond*800))
// 注意,這里要記得調(diào)用cancel(),否則即便提早執(zhí)行完了,還要傻傻等到800毫秒后context才會(huì)被釋放
defer cancel()
go func(ctx context.Context) {
// 發(fā)送HTTP請(qǐng)求
fmt.Println("處理請(qǐng)求!")
time.Sleep(800 * time.Millisecond)
fmt.Println("請(qǐng)求處理完畢!")
}(ctx)
select {
case <-ctx.Done():
fmt.Println("call successfully!!!")
return
// 這里已經(jīng)設(shè)置了context的有效時(shí)間,為何還要加上這個(gè)time.After呢
// 這是由于該方法內(nèi)的context是本身申明的,能夠手動(dòng)設(shè)置對(duì)應(yīng)的超時(shí)時(shí)間,可是在大多數(shù)場(chǎng)景,這里的ctx是從上游一直傳遞過(guò)來(lái)的,
// 對(duì)于上游傳遞過(guò)來(lái)的context還剩多少時(shí)間,咱們是不知道的,因此這時(shí)候經(jīng)過(guò)time.After設(shè)置一個(gè)本身預(yù)期的超時(shí)時(shí)間就頗有必要了
case <-time.After(time.Duration(time.Millisecond * 1000)):
fmt.Println("timeout!!!")
return
}
}程序輸出
處理請(qǐng)求!
請(qǐng)求處理完畢!
call successfully!!!
1.2 context.WithTimeout/context.WithDeadline + time.NewTimer
// time.NewTimer(time.Duration(time.Millisecond * 700))
package main
import (
"context"
"fmt"
"time"
)
// Golang三種方式實(shí)現(xiàn)超時(shí)退出-方法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請(qǐng)求
fmt.Println("處理請(qǐng)求!")
time.Sleep(800 * time.Millisecond)
fmt.Println("請(qǐng)求處理完畢!")
}(ctx)
select {
case <-ctx.Done():
timer.Stop()
timer.Reset(time.Second)
fmt.Println("call successfully!!!")
return
case <-timer.C:
fmt.Println("timeout!!!")
return
}
}程序輸出
處理請(qǐng)求!
timeout!!!
修改超時(shí)間:
// time.NewTimer(time.Duration(time.Millisecond * 1000))
package main
import (
"context"
"fmt"
"time"
)
// Golang三種方式實(shí)現(xiàn)超時(shí)退出-方法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請(qǐng)求
fmt.Println("處理請(qǐng)求!")
time.Sleep(800 * time.Millisecond)
fmt.Println("請(qǐng)求處理完畢!")
}(ctx)
select {
case <-ctx.Done():
timer.Stop()
timer.Reset(time.Second)
fmt.Println("call successfully!!!")
return
case <-timer.C:
fmt.Println("timeout!!!")
return
}
}程序輸出
處理請(qǐng)求!
請(qǐng)求處理完畢!
call successfully!!!
1.3 channel + time.After/time.NewTimer
// time.After(time.Duration(700 * time.Millisecond))
package main
import (
"context"
"fmt"
"time"
)
// Golang三種方式實(shí)現(xiàn)超時(shí)退出-方法3
// 使用通道
func main() {
ctx := context.Background()
done := make(chan struct{}, 1)
go func(ctx context.Context) {
// 發(fā)送HTTP請(qǐng)求
fmt.Println("處理請(qǐng)求!")
time.Sleep(800 * time.Millisecond)
fmt.Println("請(qǐng)求處理完畢!")
done <- struct{}{}
}(ctx)
select {
case <-done:
fmt.Println("call successfully!!!")
return
case <-time.After(time.Duration(700 * time.Millisecond)):
fmt.Println("timeout!!!")
return
}
}程序輸出
處理請(qǐng)求!
timeout!!!
修改超時(shí)時(shí)間:
// time.After(time.Duration(1000 * time.Millisecond))
package main
import (
"context"
"fmt"
"time"
)
// Golang三種方式實(shí)現(xiàn)超時(shí)退出-方法3
// 使用通道
func main() {
ctx := context.Background()
done := make(chan struct{}, 1)
go func(ctx context.Context) {
// 發(fā)送HTTP請(qǐng)求
fmt.Println("處理請(qǐng)求!")
time.Sleep(800 * time.Millisecond)
fmt.Println("請(qǐng)求處理完畢!")
done <- struct{}{}
}(ctx)
select {
case <-done:
fmt.Println("call successfully!!!")
return
case <-time.After(time.Duration(1000 * time.Millisecond)):
fmt.Println("timeout!!!")
return
}
}程序輸出
處理請(qǐng)求!
請(qǐng)求處理完畢!
call successfully!!!
到此這篇關(guān)于Go語(yǔ)言超時(shí)退出的三種實(shí)現(xiàn)方式總結(jié)的文章就介紹到這了,更多相關(guān)Go語(yǔ)言超時(shí)退出內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
golang動(dòng)態(tài)創(chuàng)建類的示例代碼
這篇文章主要介紹了golang動(dòng)態(tài)創(chuàng)建類的實(shí)例代碼,本文通過(guò)實(shí)例代碼給大家講解的非常詳細(xì),需要的朋友可以參考下2023-06-06
GOLang判斷進(jìn)程是否存在實(shí)現(xiàn)方式
該文主要介紹了使用Go語(yǔ)言編寫進(jìn)程檢測(cè)工具的方法,由于Go語(yǔ)言本身沒有直接獲取進(jìn)程信息的功能,作者決定通過(guò)執(zhí)行命令的方式實(shí)現(xiàn),最終給出了優(yōu)化后的代碼示例2026-04-04
go語(yǔ)言入門環(huán)境搭建及GoLand安裝教程詳解
這篇文章主要介紹了go語(yǔ)言入門環(huán)境搭建及GoLand安裝教程詳解,需要的朋友可以參考下2020-12-12
在Linux系統(tǒng)中安裝Go語(yǔ)言的詳細(xì)教程
這篇文章主要介紹了在Linux系統(tǒng)中安裝Go語(yǔ)言的詳細(xì)教程,由于國(guó)內(nèi)很多人對(duì)谷歌的盲目追捧,導(dǎo)致Go語(yǔ)言在國(guó)內(nèi)的人氣遠(yuǎn)超國(guó)外...需要的朋友可以參考下2015-06-06
Go語(yǔ)言封裝一個(gè)Cron定時(shí)任務(wù)管理器
在現(xiàn)代應(yīng)用中,定時(shí)任務(wù)是非常常見的需求,無(wú)論是用于定時(shí)清理數(shù)據(jù),還是定時(shí)執(zhí)行系統(tǒng)維護(hù)任務(wù),下面我們就來(lái)使用Go語(yǔ)言封裝一個(gè)Cron定時(shí)任務(wù)管理器吧2024-12-12

