Go語言超時(shí)退出的三種實(shí)現(xiàn)方式總結(jié)
1、Go語言三種方式實(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)過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是從上游一直傳遞過來的, // 對(duì)于上游傳遞過來的context還剩多少時(shí)間,咱們是不知道的,因此這時(shí)候經(jīng)過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)過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是從上游一直傳遞過來的, // 對(duì)于上游傳遞過來的context還剩多少時(shí)間,咱們是不知道的,因此這時(shí)候經(jīng)過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語言超時(shí)退出的三種實(shí)現(xiàn)方式總結(jié)的文章就介紹到這了,更多相關(guān)Go語言超時(shí)退出內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
go語言實(shí)現(xiàn)sftp包上傳文件和文件夾到遠(yuǎn)程服務(wù)器操作
這篇文章主要介紹了go語言實(shí)現(xiàn)sftp包上傳文件和文件夾到遠(yuǎn)程服務(wù)器操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-12-12Go語言中strings.HasPrefix、strings.Split、strings.SplitN()?函數(shù)
本文主要介紹了Go語言中strings.HasPrefix、strings.Split、strings.SplitN()函數(shù),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-08-08Go語言入門教程之Arrays、Slices、Maps、Range操作簡(jiǎn)明總結(jié)
這篇文章主要介紹了Go語言入門教程之Arrays、Slices、Maps、Range操作簡(jiǎn)明總結(jié),本文直接給出操作代碼,同時(shí)對(duì)代碼加上了詳細(xì)注釋,需要的朋友可以參考下2014-11-11Go語言實(shí)現(xiàn)關(guān)閉http請(qǐng)求的方式總結(jié)
面試的時(shí)候問到如何關(guān)閉http請(qǐng)求,一般人脫口而出的是關(guān)閉response.body,這是錯(cuò)誤的。本文為大家整理了三個(gè)正確關(guān)閉http請(qǐng)求的方法,希望對(duì)大家有所幫助2023-02-02Go?Singleflight導(dǎo)致死鎖問題解決分析
這篇文章主要為大家介紹了Go?Singleflight導(dǎo)致死鎖問題解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09