国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

為什么需要超時控制

這篇具有很好參考價值的文章主要介紹了為什么需要超時控制。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1. 簡介

本文將介紹為什么需要超時控制,然后詳細(xì)介紹Go語言中實現(xiàn)超時控制的方法。其中,我們將討論time包和context包實現(xiàn)超時控制的具體方式,并說明兩者的適用場景,以便在程序中以更合適的方式來實現(xiàn)超時控制,提高程序的穩(wěn)定性和可靠性。

2. 為什么需要超時控制

超時控制可以幫助我們避免程序無限期地等待某個操作完成或者防止程序因為某些原因?qū)е沦Y源泄漏。具體來說,超時控制有以下幾個優(yōu)點:

  1. 避免無限期等待:如果某個操作需要等待一段時間,但如果超過了這個時間還沒有完成,那么程序可能就需要停止等待并采取其他措施,比如返回錯誤或者取消操作。超時處理可以讓程序避免無限期等待,從而提高程序的健壯性和可靠性。
  2. 防止資源泄漏:如果程序某個操作一直處于等待狀態(tài),那么可能會導(dǎo)致資源被一直占用,從而造成資源泄漏。超時控制可以讓程序在一定時間內(nèi)完成操作,如果超時則釋放資源,從而避免資源泄漏。
  3. 提高程序響應(yīng)速度:有些操作可能需要很長時間才能完成,這可能會導(dǎo)致程序在等待過程中變得不響應(yīng)。超時控制可以讓程序在一定時間內(nèi)完成操作,如果超時則采取其他措施,從而提高程序的響應(yīng)速度。

基于以上幾點原因,我們可以看出來,在某些場景下,超時控制在程序執(zhí)行過程中必不可少。那么,在Go語言中,有哪些方式可以實現(xiàn)超時控制呢?

3. 超時控制的方法

3.1 time包實現(xiàn)超時控制

time包提供了多種方式來實現(xiàn)超時控制,包括time.After函數(shù)、time.NewTimer函數(shù)以及time.AfterFunc函數(shù),使用它們可以實現(xiàn)超時控制,下面以time.NewTimer函數(shù)為例,說明如何使用其time包實現(xiàn)超時控制。代碼示例如下:

// 創(chuàng)建一個定時器
timer := time.NewTimer(5 * time.Second)
defer timer.Stop()

// 使用一個channel來監(jiān)聽任務(wù)是否已完成
ch := make(chan string, 1)     
go func() {         
// 模擬任務(wù)執(zhí)行,休眠5秒         
    time.Sleep(2* time.Second)         
    ch <- "hello world"     
}()

// 通過select語句來等待結(jié)果,任務(wù)正常返回
select {
case <-ch:
    fmt.Println("任務(wù)正常完成")
  // ch 已經(jīng)接收到值,走正常處理邏輯
case <-timer.C:
    fmt.Println("已超時")
  // 超時,走超時邏輯
}

在這里例子中,我們使用 time.NewTimer 方法創(chuàng)建一個定時器,超時時間為2秒鐘。然后在 select 語句中使用來等待結(jié)果,哪個先返回就使用哪個。

如果操作在2秒鐘內(nèi)完成,那么任務(wù)正常完成;如果操作超過2秒鐘仍未完成,此時select語句中<-timer.C將接收到值,走超時處理邏輯。

3.2 context實現(xiàn)超時控制

Context 接口是 Go 語言標(biāo)準(zhǔn)庫中提供的一個上下文(Context)管理機(jī)制。它允許在程序的不同部分之間傳遞上下文信息,并且可以通過它實現(xiàn)超時控制、取消操作以及截斷操作等功能。其中,Context接口存在一個timerCtx的實現(xiàn),其可以設(shè)定一個超時時間,在到達(dá)超時時間后,timerCtx對象的 done channel 將會被關(guān)閉。

當(dāng)需要判斷是否超時時,只需要調(diào)用 context 對象的 Done 方法,其會返回timerCtx對象中的done channel,如果有數(shù)據(jù)返回,則說明已經(jīng)超時。基于此,我們便可以實現(xiàn)超時控制。代碼示例如下:

// 創(chuàng)建一個timerCtx,設(shè)置超時時間為3秒     
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)     
// 調(diào)用cancel函數(shù),釋放占用的資源  
defer cancel()

// 使用一個channel來監(jiān)聽任務(wù)是否已完成
ch := make(chan string, 1)     
go func() {         
// 模擬任務(wù)執(zhí)行,休眠5秒         
    time.Sleep(2* time.Second)         
    ch <- "hello world"     
}()

// 通過select語句來等待結(jié)果,任務(wù)正常返回
select {
    case <-ctx.Done():
        fmt.Println("timeout")
    case result := <-ch:
        fmt.Println(result)
}

這里通過context.WithTimeout創(chuàng)建一個timerCtx,設(shè)定好超時時間,超時時間為3s。然后啟動一個協(xié)程來執(zhí)行具體的業(yè)務(wù)邏輯。

之后通過select語句,對timerCtx和業(yè)務(wù)執(zhí)行結(jié)果同時進(jìn)行監(jiān)聽,當(dāng)任務(wù)處理超時時,則執(zhí)行超時邏輯;如果任務(wù)在超時前完成,則執(zhí)行正常處理流程。通過這種方式,實現(xiàn)了請求的超時處理。

4. 適用場景分析

從上文可以看出,timetimerCtx都可以用于實現(xiàn)超時控制,但是事實上兩者的適用場景其實是不太相同的。在某些場景下,超時控制并不適合使用time來實現(xiàn),而是使用timerCtx來實現(xiàn)更為合適。而在某些場景下,其實兩種實現(xiàn)方式均可。

下面我簡單介紹幾種常見的場景,然后對其來進(jìn)行分析,從而能夠在合適的場景下使用恰當(dāng)?shù)脤崿F(xiàn)。

4.1 簡單超時控制

舉個例子,假設(shè)我們需要從一個遠(yuǎn)程服務(wù)獲取一些數(shù)據(jù),我們可以使用Go標(biāo)準(zhǔn)庫中的http包進(jìn)行網(wǎng)絡(luò)請求,大概請求函數(shù)如下:

func makeRequest(url string) (string, error) {
   // 請求數(shù)據(jù)
}

此時為了避免請求響應(yīng)時間過長,導(dǎo)致程序長時間處于等待狀態(tài),此時我們需要對這個函數(shù)實現(xiàn)超時處理,確保程序能夠及時響應(yīng)其他請求,而不是一直等待。

為了實現(xiàn)這個目的,此時可以使用time包或者timerCtx來實現(xiàn)超時控制。在makeRequest函數(shù)中實現(xiàn)超時控制,這里代碼展示與第三點超時控制的方法中的代碼示例大體相同,這里不再贅述。而且,查看上面代碼示例,我們也可以看出來timer或者timerCtx在這個場景下,區(qū)別并不大,此時是可以相互替換的。

因此,對于這種控制某個函數(shù)的執(zhí)行時間的場景,是可以任意挑選time或者timerCtx其中一個來實現(xiàn)的。

4.2 可選超時控制

這里我們實現(xiàn)一個方法,用于建立網(wǎng)絡(luò)連接,用戶調(diào)用該方法時,傳入待建立連接的地址列表,然后該方法通過遍歷傳入的地址列表,并針對每一個地址進(jìn)行連接嘗試,直到連接成功或者所有地址都嘗試完成。函數(shù)定義如下:

func dialSerial(ras addrList) (Conn, error){
   // 執(zhí)行建立網(wǎng)絡(luò)連接的邏輯
}

基于此,在這個函數(shù)的基礎(chǔ)上,實現(xiàn)一個可選的超時控制的功能。如果用戶調(diào)用該方法時,有指定超時時間的話,此時便進(jìn)行超時控制;如果未指定超時時間的話,此時便無需執(zhí)行超時控制。這里分別使用time包以及context實現(xiàn)。

首先對于time包實現(xiàn)可選的超時控制,可以通過函數(shù)參數(shù)傳遞定時器來實現(xiàn)可選的超時控制。具體地說,可以將定時器作為一個time.Timer類型的參數(shù)傳遞給函數(shù),然后在函數(shù)中使用select監(jiān)聽time.Timer是超時;如果沒有傳遞定時器實例,則默認(rèn)不進(jìn)行超時控制,代碼實現(xiàn)如下所示:

func dialSerial(timeout time.Timer, ras addrList) (Conn, error){
   // 執(zhí)行建立網(wǎng)絡(luò)連接的邏輯,對每個地址嘗試建立連接時,先檢查是否超時
   for i, ra := range ras {
          // 通過這里來進(jìn)行超時控制,首先先判斷是否傳入定時器實例
          if timeout != nil {
              select {
              // 監(jiān)聽是否超時
              case <-timeout.C:
                  return nil, errors.New("timeout")
              default:
              }
          }
         // 執(zhí)行后續(xù)建立網(wǎng)絡(luò)連接的邏輯          
   }
}

接著則是使用timerCtx來實現(xiàn)超時控制的實現(xiàn),可以通過函數(shù)傳遞一個context.Context接口的參數(shù)來實現(xiàn)超時控制。

具體來說,用戶可以傳遞一個context.Context接口的實現(xiàn),如果有指定超時時間,則傳入一個timerCtx的實現(xiàn);如果無需超時控制,此時可以傳入context.Background,其永遠(yuǎn)不會超時。然后函數(shù)中通過調(diào)用Done方法來判斷是否超時,從而實現(xiàn)超時控制。代碼實現(xiàn)如下:

func dialSerial(ctx context.Context, ras addrList) (Conn, error){
   // 執(zhí)行建立網(wǎng)絡(luò)連接的邏輯,對每個地址嘗試建立連接時,先檢查是否超時
   for i, ra := range ras {
       select {
       case <-ctx.Done():
          return nil, &OpError{Op: "dial", Net: sd.network, Source: sd.LocalAddr, Addr: ra, Err: mapErr(ctx.Err())}
       default: 
       }
       // 執(zhí)行建立網(wǎng)絡(luò)連接的邏輯
   }
}

查看上述代碼中,dialSerial函數(shù)實現(xiàn)可選超時控制,看起來只是傳入?yún)?shù)不同,一個是傳入定時器time.Timer實例,一個是傳入context.Context接口實例而已,但是實際上不僅僅如此。

首先是代碼的可讀性上來看,傳入time.Timer實例來實現(xiàn)超時控制,并非Go中常見的實現(xiàn)方式,用戶不好理解;而對于context.Context接口來說,其被廣泛使用,如果要實現(xiàn)超時控制,用戶只需要傳入一個timerCtx實例即可,用戶使用起來沒有額外的心智負(fù)擔(dān),代碼可讀性更強(qiáng)。

其次是對于整個Go語言的生態(tài)來說,context.Context接口在Go語言標(biāo)準(zhǔn)庫中得到廣泛使用,而且普遍超時控制都是使用timerCtx來實現(xiàn)的,如果此時傳入一個time.Timer實例,實際上是與整個Go語言的超時控制的格格不入的。以上面dialSerial方法為例,其建立網(wǎng)絡(luò)連接是需要調(diào)用底層函數(shù)來協(xié)助實現(xiàn)的,如:

func (fd *netFD) connect(ctx context.Context, la, ra syscall.Sockaddr) (rsa syscall.Sockaddr, ret error) {
    // 執(zhí)行建立連接的邏輯
    switch err := connectFunc(fd.pfd.Sysfd, ra); err {
    // 未報錯,此時檢查是否超時
    case nil, syscall.EISCONN:
       select {
       case <-ctx.Done():
           // 如果已經(jīng)超時,此時返回超時錯誤
          return nil, mapErr(ctx.Err())
       default:
       }
     }
}

而且剛好,該函數(shù)也是實現(xiàn)了可選的超時控制,而且是通過timerCtx來實現(xiàn)的,如果此時傳入的timerCtx已經(jīng)超時,此時函數(shù)會直接返回一個超時錯誤。

如果上面dialSerial的超時控制是通過context.Context的接口實例來實現(xiàn)的話,此時調(diào)用函數(shù)時,直接將外部的Context實例作為參數(shù)傳入connect函數(shù),外層調(diào)用也無需再檢查函數(shù)是否超時,代碼的可復(fù)用性更高。

相對的,如果dialSerial的超時控制是通過傳入定時器實現(xiàn)的,此時便無法很好利用connect方法已經(jīng)實現(xiàn)的超時檢查的機(jī)制。

因此,綜上所述,使用 context.Context 接口作為可選的超時控制參數(shù),相比于使用 time.Timer,更加適合同時也更加高效,與整個Go語言的實現(xiàn)也能夠更好得進(jìn)行融合在一起。

4.3 總結(jié)

ContextTime 都是 Go 語言中實現(xiàn)超時控制的方法,它們各有優(yōu)缺點,不能說哪一種實現(xiàn)更好,要根據(jù)具體的場景來選擇使用哪種方法。

在一些簡單的場景下,使用 Time 包實現(xiàn)超時控制可能更加方便,因為它的 API 更加簡單,只需要使用 time.After() 函數(shù)即可實現(xiàn)超時控制。

但是,如果涉及到在多個函數(shù),或者是需要多個goroutine之間傳遞的話,此時使用Context來實現(xiàn)超時控制可能更加適合。

5.總結(jié)

本文介紹了需要超時控制的原因,主要是避免無限期等待,防止資源泄漏和提高程序響應(yīng)速度這幾點內(nèi)容。

接著我們介紹了Go語言中實現(xiàn)超時控制的方法,包括使用time實現(xiàn)超時控制以及使用context實現(xiàn)超時控制,并給出了簡單的代碼示例。

在接下來,我們便這兩種實現(xiàn)的適用場景進(jìn)行分析,明確了在哪些場景下,適合使用time實現(xiàn)超時控制,以及在哪些場景下,使用timerCtx來實現(xiàn)更為高效。

基于此,完成了為什么需要超時控制的介紹,希望能夠讓大家在遇到需要超時控制的場景下,更好得去進(jìn)行實現(xiàn)。文章來源地址http://www.zghlxwxcb.cn/news/detail-435727.html

到了這里,關(guān)于為什么需要超時控制的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 為什么需要單元測試?

    為什么需要單元測試?

    為什么需要單元測試? 從產(chǎn)品角度而言,常規(guī)的功能測試、系統(tǒng)測試都是站在產(chǎn)品局部或全局功能進(jìn)行測試,能夠很好地與用戶的需要相結(jié)合,但是缺乏了對產(chǎn)品研發(fā)細(xì)節(jié)(特別是代碼細(xì)節(jié)的理解)。 從測試人員角度而言,功能測試和系統(tǒng)測試以及其他性能測試等等對測試

    2024年02月12日
    瀏覽(34)
  • 為什么需要uboot?

    bootROM: 一種固化在芯片內(nèi)部的只讀存儲器(ROM),用于啟動和初始化系統(tǒng)。BootROM 中通常包含了一些預(yù)先編寫好的代碼,用于完成系統(tǒng)啟動前的基本初始化和配置, 例如初始化時鐘、GPIO控制器、中斷控制器、存儲設(shè)備(SD卡、NAND Flash、SPicy Flash)等硬件資源, 檢測啟動設(shè)備

    2023年04月23日
    瀏覽(21)
  • 為什么需要websocket?

    為什么需要websocket?

    前端和后端的交互模式最常見的就是前端發(fā)數(shù)據(jù)請求,從后端拿到數(shù)據(jù)后展示到頁面中。如果前端不做操作,后端不能主動向前端推送數(shù)據(jù),這也是http協(xié)議的缺陷。 ? ? ? ?因此,一種新的通信協(xié)議應(yīng)運而生---websocket,他最大的特點就是服務(wù)端可以主動向客戶端推送消息,客

    2024年02月12日
    瀏覽(31)
  • [WinError 10038] 在一個非套接字上嘗試了一個操作,這是許多編程人員經(jīng)常遇到的錯誤之一。本文將解釋什么是套接字,為什么會出現(xiàn) WinError 1...

    [WinError 10038] 在一個非套接字上嘗試了一個操作,這是許多編程人員經(jīng)常遇到的錯誤之一。本文將解釋什么是套接字,為什么會出現(xiàn) WinError 10038 錯誤以及如何解決該錯誤。 在計算機(jī)網(wǎng)絡(luò)編程中,套接字是一個端點,用于發(fā)送和接收網(wǎng)絡(luò)數(shù)據(jù)。它可以是客戶端或服務(wù)器端,并與

    2024年02月16日
    瀏覽(84)
  • 為什么CPU需要時鐘

    為什么CPU需要時鐘

    為什么CPU需要時鐘這樣一個概念? 什么是時鐘脈沖,CPU為什么需要時鐘,時鐘信號是怎么產(chǎn)生的? 上面這個圖的方波就是一個脈沖,類比于人類的脈搏跳動。一個脈沖稱之為CPU的一個 時鐘信號 ,或者 時鐘脈沖 。一個脈沖周期就叫CPU時鐘周期,一個時鐘周期內(nèi)時鐘信號震蕩一

    2023年04月11日
    瀏覽(21)
  • 為什么自動駕駛需要5G?

    為什么自動駕駛需要5G?

    什么叫自動駕駛? 自動駕駛分為6個等級: Level 0: 人工駕駛,無駕駛輔助系統(tǒng),僅提醒。 Level 1: 輔助人工駕駛,可實現(xiàn)單一的車速或轉(zhuǎn)向控制自動化,仍由人工駕駛(如定速巡航、ACC)。 Level 2: 部分自動駕駛,可實現(xiàn)車速和轉(zhuǎn)向控制自動化,駕駛員必須始終保持監(jiān)控(

    2024年02月08日
    瀏覽(35)
  • 為什么需要對相機(jī)標(biāo)定?

    為什么需要對相機(jī)標(biāo)定?

    以下內(nèi)容來自系統(tǒng)教程如何搞定單目/魚眼/雙目/陣列 相機(jī)標(biāo)定? 點擊領(lǐng)取相機(jī)標(biāo)定資料和代碼 為什么需要對相機(jī)標(biāo)定? 我們所處的世界是三維的,而相機(jī)拍攝的照片卻是二維的,丟失了其中距離/深度的信息。從數(shù)學(xué)上可以簡單理解為,相機(jī)本身類似一個映射函數(shù),其將輸

    2024年02月06日
    瀏覽(25)
  • 爬蟲時為什么需要代理?

    我們都知道爬蟲時是需要代理地址介入的。使用代理可以隱藏你的真實IP地址,防止被網(wǎng)站封禁或限制訪問。此外,代理還可以幫助你繞過地理限制,訪問被封鎖的網(wǎng)站或服務(wù)。但是請注意,使用代理也可能會帶來一些風(fēng)險,例如代理服務(wù)器可能會記錄你的訪問數(shù)據(jù),或者代

    2024年02月06日
    瀏覽(25)
  • 爬蟲為什么需要ip

    爬蟲為什么需要ip

    爬蟲需要使用爬蟲ip主要是為了解決以下問題: 1、反爬蟲機(jī)制:許多網(wǎng)站會設(shè)置反爬蟲機(jī)制來防止爬蟲程序的訪問,例如限制IP地址的訪問頻率、檢測訪問來源等。使用爬蟲ip可以繞過這些限制,使得爬蟲程序更難被檢測到。 2、訪問限制:有些網(wǎng)站可能會對某些地區(qū)的IP地址

    2024年02月02日
    瀏覽(27)
  • 什么是分庫分表?為什么需要分表?什么時候分庫分表

    什么是分庫分表?為什么需要分表?什么時候分庫分表

    不急于上手實戰(zhàn)? ShardingSphere ?框架,先來復(fù)習(xí)下分庫分表的基礎(chǔ)概念,技術(shù)名詞大多晦澀難懂,不要死記硬背理解最重要,當(dāng)你捅破那層窗戶紙,發(fā)現(xiàn)其實它也就那么回事。 分庫分表是在海量數(shù)據(jù)下,由于單庫、表數(shù)據(jù)量過大,導(dǎo)致數(shù)據(jù)庫性能持續(xù)下降的問題,演變出的技

    2023年04月26日
    瀏覽(53)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包