日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

Golang 中的 Context 包

來源: 責編: 時間:2023-11-14 09:10:08 281觀看
導讀今天,我們將討論 Go 編程中非常重要的一個主題:context 包。如果你現(xiàn)在覺得它很令人困惑,不用擔心 — 在本文結束時,你將像專家一樣處理 context!想象一下,你在一個主題公園,興奮地準備搭乘一座巨大的過山車。但有個問題:排隊

今天,我們將討論 Go 編程中非常重要的一個主題:context 包。如果你現(xiàn)在覺得它很令人困惑,不用擔心 — 在本文結束時,你將像專家一樣處理 context!Thv28資訊網(wǎng)——每日最新資訊28at.com

想象一下,你在一個主題公園,興奮地準備搭乘一座巨大的過山車。但有個問題:排隊的人非常多,而且公園快要關門,你只有一個小時的時間。你會怎么辦?嗯,你可能會等一會兒,但不會等一個小時,對吧?如果你等了 30 分鐘還沒有到前面,你會離開隊伍去嘗試其他游樂設施。這就是我們所謂的 '超時'。Thv28資訊網(wǎng)——每日最新資訊28at.com

Thv28資訊網(wǎng)——每日最新資訊28at.com

現(xiàn)在,想象一下,你還在排隊,突然下起了傾盆大雨。過山車的操作員決定關閉過山車。你不會繼續(xù)排隊等待根本不會發(fā)生的事情,對吧?你會立刻離開隊伍。這就是我們所謂的 '取消'。Thv28資訊網(wǎng)——每日最新資訊28at.com

在編程世界中,我們經(jīng)常面臨類似的情況。我們要求程序執(zhí)行可能需要很長時間或需要因某種原因停止的任務。這就是 context 包發(fā)揮作用的地方。它允許我們優(yōu)雅地處理這些超時和取消。Thv28資訊網(wǎng)——每日最新資訊28at.com

它是如何工作的

(1) 創(chuàng)建上下文:我們首先創(chuàng)建一個上下文。這就像排隊等待過山車一樣。Thv28資訊網(wǎng)——每日最新資訊28at.com

ctx := context.Background() // This gives you an empty context

(2) 設置超時:接下來,我們可以在上下文中設置超時。這就好比你決定在排隊多久后放棄并去嘗試其他游樂設施。Thv28資訊網(wǎng)——每日最新資訊28at.com

ctxWithTimeout, cancel := context.WithTimeout(ctx, time.Second*10) // Wait for 10 seconds// Don't forget to call cancel when you're done, or else you might leak resources!defer cancel()

(3) 檢查超時:現(xiàn)在,我們可以使用上下文來檢查是否等待時間太長,是否應該停止我們的任務。這就好比在排隊等待時看看手表。Thv28資訊網(wǎng)——每日最新資訊28at.com

select {case <-time.After(time.Second * 15): // This task takes 15 seconds    fmt.Println("Finished the task")case <-ctxWithTimeout.Done():    fmt.Println("We've waited too long, let's move on!") // We only wait for 10 seconds}

(4) 取消上下文:最后,如果出于某種原因需要停止任務,我們可以取消上下文。這就好比聽到因下雨而宣布過山車關閉。Thv28資訊網(wǎng)——每日最新資訊28at.com

cancel() // We call the cancel function we got when we created our context with timeout

示例 1:慢速數(shù)據(jù)庫查詢

想象一下構建一個從數(shù)據(jù)庫中獲取用戶數(shù)據(jù)的Web應用程序。有時,數(shù)據(jù)庫響應較慢,你不希望用戶永遠等下去。在這種情況下,你可以使用帶有超時的上下文。Thv28資訊網(wǎng)——每日最新資訊28at.com

func getUser(ctx context.Context, id int) (*User, error) {    // Create a new context that will be cancelled if it takes more than 3 seconds    ctx, cancel := context.WithTimeout(ctx, 3*time.Second)    defer cancel()    // Assume db.QueryRowContext is a function that executes a SQL query and returns a row    row := db.QueryRowContext(ctx, "SELECT name FROM users WHERE id = ?", id)    var name string    if err := row.Scan(&name); err != nil {        return nil, err    }    return &User{Name: name}, nil}

在這個示例中,如果數(shù)據(jù)庫查詢花費超過3秒的時間,上下文將被取消,db.QueryRowContext 應返回一個錯誤。Thv28資訊網(wǎng)——每日最新資訊28at.com

示例 2:網(wǎng)頁抓取

假設你正在編寫一個用于從網(wǎng)站抓取數(shù)據(jù)的程序。然而,該網(wǎng)站有時響應較慢,或者根本不響應。你可以使用上下文來防止你的程序陷入困境。Thv28資訊網(wǎng)——每日最新資訊28at.com

func scrapeWebsite(ctx context.Context, url string) (*html.Node, error) {    // Create a new context that will be cancelled if it takes more than 5 seconds    ctx, cancel := context.WithTimeout(ctx, 5*time.Second)    defer cancel()    // Create a request with the context    req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)    if err != nil {        return nil, err    }    // Execute the request    resp, err := http.DefaultClient.Do(req)    if err != nil {        return nil, err    }    defer resp.Body.Close()    // Parse the response body as HTML    return html.Parse(resp.Body), nill}

在這個示例中,如果從網(wǎng)站獲取數(shù)據(jù)超過5秒,上下文將被取消,http.DefaultClient.Do 應該返回一個錯誤。Thv28資訊網(wǎng)——每日最新資訊28at.com

示例3:長時間運行的任務

假設你有一個執(zhí)行長時間運行任務的程序,但你希望能夠在程序接收到關閉信號時停止任務。這在一個 Web 服務器中可能會很有用,當關閉時必須停止提供請求并進行清理。Thv28資訊網(wǎng)——每日最新資訊28at.com

func doTask(ctx context.Context) {    for {        select {        case <-time.After(1 * time.Second):            // The task is done, we're ready to exit            fmt.Println("Task is done")            return        case <-ctx.Done():            // The context was cancelled from the outside, clean up and exit            fmt.Println("Got cancel signal, cleaning up")            return        }    }}func main() {    // Create a new context    ctx, cancel := context.WithCancel(context.Background())    // Start the task in a goroutine    go doTask(ctx)    // Wait for a shutdown signal    <-getShutdownSignal()    // Cancel the context, which will stop the task    cancel()    // Wait for a bit to allow the task to clean up    time.Sleep(1 * time.Second)}

在這個示例中,當程序接收到關閉信號時,它會取消上下文,這會導致 doTask 在 <-ctx.Done() 上接收到信號。Thv28資訊網(wǎng)——每日最新資訊28at.com

示例4:HTTP 服務器

假設你正在構建一個處理傳入請求的 HTTP 服務器。一些請求可能需要很長時間來處理,你希望設置一個最長處理時間限制。Thv28資訊網(wǎng)——每日最新資訊28at.com

http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {    ctx, cancel := context.WithTimeout(r.Context(), 2*time.Second)    defer cancel()    // Simulate a long-running operation    select {    case <-time.After(3 * time.Second):        w.Write([]byte("Operation finished."))    case <-ctx.Done():        w.Write([]byte("Operation timed out."))    }})http.ListenAndServe(":8080", nil)

在這個示例中,如果操作需要超過2秒的時間,上下文將被取消,并且服務器將響應“操作超時”。Thv28資訊網(wǎng)——每日最新資訊28at.com

示例5:同步多個 Goroutines

假設你正在編寫一個程序,使用 Goroutines 并發(fā)執(zhí)行多個任務。如果其中一個任務失敗,你希望取消所有其他任務。Thv28資訊網(wǎng)——每日最新資訊28at.com

func doTask(ctx context.Context, id int) {    select {    case <-time.After(time.Duration(rand.Intn(4)) * time.Second):        fmt.Printf("Task %v finished./n", id)    case <-ctx.Done():        fmt.Printf("Task %v cancelled./n", id)    }}func main() {    ctx, cancel := context.WithCancel(context.Background())    for i := 1; i <= 5; i++ {        go doTask(ctx, i)    }    // Cancel the context after 2 seconds    time.Sleep(2 * time.Second)    cancel()    // Give the tasks some time to finish up    time.Sleep(1 * time.Second)}

在這個示例中,當上下文被取消時,仍在運行的任何任務都將收到 <-ctx.Done(),從而允許它們進行清理并退出。Thv28資訊網(wǎng)——每日最新資訊28at.com

仍然在嘗試理解嗎?

當我第一次接觸上下文時,我感到非常困惑,我提出了一個問題,即如果 select 前面的命令花費太長時間,那么我們永遠無法檢測到 取消,這是一個合理的問題。因此,我準備了另一個示例來詳細解釋這種情況。Thv28資訊網(wǎng)——每日最新資訊28at.com

package mainimport ( "context" "fmt" "math/rand" "time")func expensiveCalculation(ctx context.Context, resultChan chan<- int) { // Simulate a long-running calculation rand.Seed(time.Now().UnixNano()) sleepTime := time.Duration(rand.Intn(20)+1) * time.Second fmt.Printf("Calculation will take %s to complete/n", sleepTime) time.Sleep(sleepTime) select { case <-ctx.Done():  // Context was cancelled, don't write to the channel  return default:  // Write the result to the channel  resultChan <- 42 // replace with your actual calculation result }}func main() { // Create a context that will be cancelled after 10 seconds ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() // The cancel should be deferred so resources are cleaned up resultChan := make(chan int) // Start the expensive calculation in a separate goroutine go expensiveCalculation(ctx, resultChan) // Wait for either the result or the context to be done select { case res := <-resultChan:  // Got the result  fmt.Printf("Calculation completed with result: %d/n", res) case <-ctx.Done():  // Context was cancelled  fmt.Println("Calculation cancelled") }}

time.Sleep(sleepTime) 命令是阻塞的,將暫停 goroutine 的執(zhí)行,直到指定的持續(xù)時間已過。這意味著 select 語句不會被執(zhí)行,直到休眠時間已經(jīng)過去。Thv28資訊網(wǎng)——每日最新資訊28at.com

然而,上下文的取消與 goroutine 內的執(zhí)行是獨立的。如果上下文的截止時間被超過或其 cancel() 函數(shù)被調用,它的 Done() 通道將被關閉。Thv28資訊網(wǎng)——每日最新資訊28at.com

在主 goroutine 中,您有另一個 select 語句,它將立即檢測上下文的 Done() 通道是否已關閉,并在不等待 expensiveCalculation goroutine 完成休眠的情況下打印 **"Calculation cancelled"**。Thv28資訊網(wǎng)——每日最新資訊28at.com

也就是說,expensiveCalculation goroutine 將在休眠后繼續(xù)執(zhí)行,它將在嘗試寫入 resultChan 之前檢查上下文是否已被取消。如果已被取消,它將立即返回。這是為了避免潛在的死鎖,如果沒有其他goroutine從 resultChan 讀取。Thv28資訊網(wǎng)——每日最新資訊28at.com

如果需要昂貴的計算(在本例中由 time.Sleep 模擬)在取消時立即停止,您必須設計計算以周期性地檢查上下文是否已取消。這通常在需要將計算分解為較小部分的情況下使用循環(huán)。如果計算不能分解,并需要一次運行完畢,那么很遺憾,在 Go 中無法提前停止它。Thv28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-24320-0.htmlGolang 中的 Context 包

聲明:本網(wǎng)頁內容旨在傳播知識,若有侵權等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: C 語言編譯器(IDE)初學者指南:選擇適合你的工具

下一篇: 使用Python進行文本分析-將PDF文件多進程批量處理為csv文件

標簽:
  • 熱門焦點
  • 5月iOS設備性能榜:M1 M2依舊是榜單前五

    和上個月一樣,沒有新品發(fā)布的iOS設備性能榜的上榜設備并沒有什么更替,僅僅只有跑分變化而產生的排名變動,剛剛開始的蘋果WWDC2023,推出的產品也依舊是新款Mac Pro、新款Mac Stu
  • 5月安卓手機好評榜:魅族20 Pro奪冠

    性能榜和性價比榜之后,我們來看最后的安卓手機好評榜,數(shù)據(jù)來源安兔兔評測,收集時間2023年5月1日至5月31日,僅限國內市場。第一名:魅族20 Pro好評率:97.50%不得不感慨魅族老品牌還
  • K8S | Service服務發(fā)現(xiàn)

    一、背景在微服務架構中,這里以開發(fā)環(huán)境「Dev」為基礎來描述,在K8S集群中通常會開放:路由網(wǎng)關、注冊中心、配置中心等相關服務,可以被集群外部訪問;圖片對于測試「Tes」環(huán)境或者
  • 不容錯過的MSBuild技巧,必備用法詳解和實踐指南

    一、MSBuild簡介MSBuild是一種基于XML的構建引擎,用于在.NET Framework和.NET Core應用程序中自動化構建過程。它是Visual Studio的構建引擎,可在命令行或其他構建工具中使用
  • 一篇文章帶你了解 CSS 屬性選擇器

    屬性選擇器對帶有指定屬性的 HTML 元素設置樣式。可以為擁有指定屬性的 HTML 元素設置樣式,而不僅限于 class 和 id 屬性。一、了解屬性選擇器CSS屬性選擇器提供了一種簡單而
  • JVM優(yōu)化:實戰(zhàn)OutOfMemoryError異常

    一、Java堆溢出堆內存中主要存放對象、數(shù)組等,只要不斷地創(chuàng)建這些對象,并且保證 GC Roots 到對象之間有可達路徑來避免垃 圾收集回收機制清除這些對象,當這些對象所占空間超過
  • 小米汽車電池信息疑似曝光:容量101kWh,支持800V高壓快充

    7月14日消息,今日一名博主在社交媒體發(fā)布了一張疑似小米汽車電池信息的照片,顯示該電池包正是寧德時代麒麟電池,容量為101kWh,電壓為726.7V,可以預測小
  • 最薄的14英寸游戲筆記本電腦 Alienware X14已可以購買

    2022年1月份在國際消費電子展(CES2022)上首次亮相的Alienware新品——Alienware X14現(xiàn)在已經(jīng)可以購買了,這款筆記本電腦被譽為世界上最薄的 14 英寸游戲筆
  • 利用職權私自解除被封帳號 Meta開除20多名員工

    11月18日消息,據(jù)外媒援引知情人士表示,過去一年時間內,F(xiàn)acebook母公司Meta解雇或處罰了20多名員工以及合同工,指控這些人通過內部系統(tǒng)以不當方式重置用戶帳號,其
Top 主站蜘蛛池模板: 交口县| 正蓝旗| 衡南县| 古蔺县| 凉山| 新民市| 澄城县| 霸州市| 五河县| 连山| 正镶白旗| 探索| 扎囊县| 桦南县| 仙桃市| 天镇县| 黎川县| 志丹县| 阜城县| 晴隆县| 秦皇岛市| 迁安市| 齐河县| 翁源县| 咸宁市| 昭平县| 万源市| 合山市| 闵行区| 来凤县| 梁山县| 时尚| 温泉县| 措勤县| 宁阳县| 黎平县| 临武县| 饶河县| 景宁| 兴安县| 津南区|