欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Golang并發(fā)編程中Context包的使用與并發(fā)控制

 更新時間:2024年11月18日 10:38:09   作者:Linke-  
Golang的context包提供了在并發(fā)編程中傳遞取消信號、超時控制和元數(shù)據(jù)的功能,本文就來介紹一下Golang并發(fā)編程中Context包的使用與并發(fā)控制,感興趣的可以了解一下

一、簡介

在并發(fā)編程中,任務(wù)管理和資源控制是非常重要的,而 Golang 的 context 包 為我們提供了一種優(yōu)雅的方式來傳遞取消信號超時控制Context 用于在多個 Goroutine 之間傳遞上下文信息,避免 Goroutine 無法按需停止而導致資源浪費。

本篇博客將詳細介紹 context 包的用法,并通過實例講解如何在超時、取消任務(wù)多 Goroutine 協(xié)作場景中使用它。

二、Context 的基本概念

Context 是一種攜帶取消信號、截止時間(超時)和元數(shù)據(jù)的上下文對象,主要用于父 Goroutine 與子 Goroutine 的協(xié)作。它通過層級化的結(jié)構(gòu)來管理多個并發(fā)任務(wù)。

1. context 包常用函數(shù)

  • context.Background():創(chuàng)建根上下文,通常用于程序入口。
  • context.TODO():占位符上下文,表示未來會替換為實際上下文。
  • context.WithCancel(parent Context):創(chuàng)建帶取消功能的子上下文。
  • context.WithTimeout(parent Context, timeout time.Duration):創(chuàng)建帶超時功能的子上下文。
  • context.WithDeadline(parent Context, deadline time.Time):基于指定的截止時間創(chuàng)建上下文。
  • context.WithValue(parent Context, key, value interface{}):傳遞攜帶額外數(shù)據(jù)的上下文。

三、Context 的基本用法

1. WithCancel:取消任務(wù)的上下文

示例:使用 WithCancel 取消 Goroutine

package main

import (
    "context"
    "fmt"
    "time"
)

func worker(ctx context.Context, id int) {
    for {
        select {
        case <-ctx.Done(): // 接收取消信號
            fmt.Printf("Worker %d stopped\n", id)
            return
        default:
            fmt.Printf("Worker %d is working...\n", id)
            time.Sleep(time.Second)
        }
    }
}

func main() {
    ctx, cancel := context.WithCancel(context.Background()) // 創(chuàng)建可取消的上下文

    for i := 1; i <= 3; i++ {
        go worker(ctx, i)
    }

    time.Sleep(3 * time.Second) // 模擬主 Goroutine 的其他工作
    fmt.Println("Cancelling all workers...")
    cancel() // 發(fā)送取消信號

    time.Sleep(1 * time.Second) // 等待所有 Goroutine 退出
    fmt.Println("All workers stopped.")
}

輸出:

Worker 1 is working...
Worker 2 is working...
Worker 3 is working...
...
Cancelling all workers...
Worker 1 stopped
Worker 2 stopped
Worker 3 stopped
All workers stopped.

解析:

context.WithCancel 創(chuàng)建的上下文可以通過調(diào)用 cancel() 發(fā)送取消信號,從而優(yōu)雅地停止所有子 Goroutine。

四、超時控制:WithTimeout 和 WithDeadline

1. 使用 WithTimeout 控制任務(wù)超時

示例:在 2 秒內(nèi)完成任務(wù),否則超時退出

package main

import (
    "context"
    "fmt"
    "time"
)

func worker(ctx context.Context) {
    select {
    case <-time.After(3 * time.Second): // 模擬長時間任務(wù)
        fmt.Println("Task completed")
    case <-ctx.Done(): // 接收超時信號
        fmt.Println("Task timed out")
    }
}

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) // 設(shè)置 2 秒超時
    defer cancel() // 確保資源釋放

    go worker(ctx)

    time.Sleep(4 * time.Second) // 等待任務(wù)完成或超時
}

輸出:

Task timed out

解析:

  • 通過 context.WithTimeout 創(chuàng)建的上下文,2 秒內(nèi)未完成任務(wù)時自動發(fā)送取消信號。
  • 超時上下文可避免 Goroutine 無限期運行,幫助更好地管理資源。

2. 使用 WithDeadline 設(shè)定截止時間

WithDeadline 和 WithTimeout 類似,只是使用具體的時間點來控制超時。

五、傳遞上下文中的數(shù)據(jù):WithValue

有時,我們需要在多個 Goroutine 之間傳遞一些元數(shù)據(jù)。WithValue 允許我們將鍵值對存入上下文,并在子 Goroutine 中訪問。

示例:傳遞用戶信息

package main

import (
    "context"
    "fmt"
    "time"
)

func greetUser(ctx context.Context) {
    if user, ok := ctx.Value("user").(string); ok {
        fmt.Printf("Hello, %s!\n", user)
    } else {
        fmt.Println("No user found.")
    }
}

func main() {
    ctx := context.WithValue(context.Background(), "user", "Alice") // 在上下文中存入用戶信息
    go greetUser(ctx)

    time.Sleep(1 * time.Second) // 確保 Goroutine 執(zhí)行完畢
}

輸出:

Hello, Alice!

解析:

WithValue 允許我們?yōu)樯舷挛脑O(shè)置鍵值對,便于在多 Goroutine 間傳遞數(shù)據(jù)。

注意:

不建議用 WithValue 傳遞重要的控制信息,例如取消信號或超時。

六、Context 的應(yīng)用場景

  • API 請求的超時控制:確保 HTTP 請求不會無限期等待。
  • 任務(wù)取消:當用戶主動取消某個操作時,通知相關(guān)的 Goroutine 停止工作。
  • 傳遞元數(shù)據(jù):例如在服務(wù)鏈路中傳遞用戶身份、請求 ID 等信息。

七、完整示例:多任務(wù)協(xié)作控制

示例:啟動多個任務(wù),隨時可取消所有任務(wù)

package main

import (
    "context"
    "fmt"
    "sync"
    "time"
)

func worker(ctx context.Context, id int, wg *sync.WaitGroup) {
    defer wg.Done()

    for {
        select {
        case <-ctx.Done():
            fmt.Printf("Worker %d stopped\n", id)
            return
        default:
            fmt.Printf("Worker %d is processing...\n", id)
            time.Sleep(500 * time.Millisecond)
        }
    }
}

func main() {
    var wg sync.WaitGroup
    ctx, cancel := context.WithCancel(context.Background()) // 創(chuàng)建上下文

    for i := 1; i <= 3; i++ {
        wg.Add(1)
        go worker(ctx, i, &wg)
    }

    time.Sleep(2 * time.Second)
    fmt.Println("Cancelling all workers...")
    cancel() // 取消所有任務(wù)

    wg.Wait() // 等待所有任務(wù)完成
    fmt.Println("All workers stopped.")
}

輸出:

Worker 1 is processing...
Worker 2 is processing...
Worker 3 is processing...
...
Cancelling all workers...
Worker 1 stopped
Worker 2 stopped
Worker 3 stopped
All workers stopped.

八、小結(jié)

  • Context 用于并發(fā)控制:在 Goroutine 中傳遞取消信號、超時信號或攜帶元數(shù)據(jù)。
  • 超時控制與資源管理:使用 WithTimeout 和 WithCancel 及時終止任務(wù),避免資源浪費。
  • 多 Goroutine 協(xié)作:通過 Context 實現(xiàn)多個 Goroutine 之間的優(yōu)雅通信。

到此這篇關(guān)于Golang并發(fā)編程中Context包的使用與并發(fā)控制的文章就介紹到這了,更多相關(guān)Golang Context包使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • golang實現(xiàn)枚舉的幾種方式

    golang實現(xiàn)枚舉的幾種方式

    在Go語言中,雖沒有內(nèi)置枚舉類型,但可通過常量、結(jié)構(gòu)體或自定義類型和方法實現(xiàn)枚舉功能,這些方法提高了代碼的可讀性和維護性,避免了魔法數(shù)字的使用,感興趣的可以了解一下
    2024-09-09
  • Go設(shè)計模式之狀態(tài)模式圖文詳解

    Go設(shè)計模式之狀態(tài)模式圖文詳解

    狀態(tài)模式是一種行為設(shè)計模式, 讓你能在一個對象的內(nèi)部狀態(tài)變化時改變其行為, 使其看上去就像改變了自身所屬的類一樣,本文將通過一些圖片來給大家詳細的介紹一下Go的狀態(tài)模式,需要的朋友可以參考下
    2023-08-08
  • Go 語言數(shù)據(jù)結(jié)構(gòu)之雙鏈表學習教程

    Go 語言數(shù)據(jù)結(jié)構(gòu)之雙鏈表學習教程

    這篇文章主要為大家介紹了Go 語言數(shù)據(jù)結(jié)構(gòu)之雙鏈表學習教程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • 使用Golang的singleflight防止緩存擊穿的方法

    使用Golang的singleflight防止緩存擊穿的方法

    這篇文章主要介紹了使用Golang的singleflight防止緩存擊穿的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-04-04
  • Go routine調(diào)度詳解

    Go routine調(diào)度詳解

    這篇文章主要介紹了Go routine調(diào)度詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-01-01
  • golang 實現(xiàn)每隔幾分鐘執(zhí)行一個函數(shù)

    golang 實現(xiàn)每隔幾分鐘執(zhí)行一個函數(shù)

    這篇文章主要介紹了golang 實現(xiàn)每隔幾分鐘執(zhí)行一個函數(shù),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • go?zero微服務(wù)實戰(zhàn)系服務(wù)拆分

    go?zero微服務(wù)實戰(zhàn)系服務(wù)拆分

    這篇文章主要為大家介紹了go?zero微服務(wù)實戰(zhàn)系服務(wù)拆分的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • 詳解Go語言中如何高效遍歷目錄

    詳解Go語言中如何高效遍歷目錄

    目錄遍歷是一個很常見的操作,它的使用場景有如文件目錄查看、文件系統(tǒng)清理、日志分析、項目構(gòu)建等,本文將詳細介紹在Go中幾種遍歷目錄文件的方法,需要的可以參考下
    2024-02-02
  • golang jwt+token驗證的實現(xiàn)

    golang jwt+token驗證的實現(xiàn)

    這篇文章主要介紹了golang jwt+token驗證的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-10-10
  • 詳解Golang開啟http服務(wù)的三種方式

    詳解Golang開啟http服務(wù)的三種方式

    這篇文章主要介紹了詳解Golang開啟http服務(wù)的三種方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-06-06

最新評論