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

Go語言使用context控制協(xié)程取消的方法步驟

 更新時間:2025年08月14日 10:23:43   作者:程序員愛釣魚  
本文將通過一個實際案例,使用?context?控制協(xié)程的取消,避免資源泄露,實現(xiàn)優(yōu)雅退出,具有一定的參考價值,感興趣的可以了解一下

在并發(fā)編程中,合理地控制協(xié)程(goroutine)的生命周期是保證程序穩(wěn)定性和資源可控使用的關鍵。Go語言標準庫中的 context 包正是為了解決這一問題而生。它為我們提供了取消信號、超時控制、請求作用域的值傳遞等功能。

本文將通過一個實際案例,演示如何使用 context 控制協(xié)程的取消,避免資源泄露,實現(xiàn)優(yōu)雅退出。

一、什么是context

context 是 Go 1.7 起加入標準庫的一個重要包,用于跨 API 邊界傳遞取消信號、超時時間、截止時間等信息。

主要接口定義如下:

type Context interface {
    Deadline() (deadline time.Time, ok bool)
    Done() <-chan struct{}
    Err() error
    Value(key any) any
}

其中最關鍵的是:

  • • Done():返回一個 channel,當 context 被取消或超時關閉時,該 channel 會被關閉;
  • • Err():返回取消的原因,例如 context.Canceled 或 context.DeadlineExceeded

二、常見創(chuàng)建方式

Go 提供了以下常用方式創(chuàng)建 context:

ctx := context.Background() // 最頂層、永不取消的 context
ctx, cancel := context.WithCancel(parent) // 手動調用 cancel() 取消
ctx, cancel := context.WithTimeout(parent, 3*time.Second) // 指定超時時間
ctx, cancel := context.WithDeadline(parent, time.Now().Add(3*time.Second)) // 到期時間點

這些 context 都可以傳遞到協(xié)程中,通過 ctx.Done() 控制協(xié)程的停止。

三、實戰(zhàn)案例:使用context控制任務協(xié)程

場景描述

假設我們要運行一個任務,該任務每秒輸出一次“正在處理”,但當主程序在某個時機需要終止它(比如點擊“停止按鈕”或超時),我們要優(yōu)雅地通知協(xié)程退出。

示例代碼

package main

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

func worker(ctx context.Context) {
    for {
        select {
        case <-ctx.Done():
            fmt.Println("worker 任務被取消:", ctx.Err())
            return
        default:
            fmt.Println("worker 正在處理任務...")
            time.Sleep(1 * time.Second)
        }
    }
}

func main() {
    ctx, cancel := context.WithCancel(context.Background())

    go worker(ctx)

    // 主線程運行5秒后取消任務
    time.Sleep(5 * time.Second)
    cancel()

    // 等待協(xié)程打印結束語
    time.Sleep(1 * time.Second)
    fmt.Println("主程序退出")
}

輸出結果

worker 正在處理任務...
worker 正在處理任務...
worker 正在處理任務...
worker 正在處理任務...
worker 正在處理任務...
worker 任務被取消: context canceled
主程序退出

可以看到,主程序通過 cancel() 取消了 context,協(xié)程立即響應退出了。

四、使用context.WithTimeout實現(xiàn)超時控制

除了手動調用 cancel,我們還可以通過設定超時時間自動取消任務。

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
    defer cancel()

    go worker(ctx)

    time.Sleep(5 * time.Second) // 主線程等待更久,看任務是否能自動終止
    fmt.Println("主程序退出")
}

運行結果類似:

worker 正在處理任務...
worker 正在處理任務...
worker 正在處理任務...
worker 任務被取消: context deadline exceeded
主程序退出

這表示:即使主程序沒有主動調用 cancel(),協(xié)程也在 3 秒后收到 context 超時通知并正常退出。

五、多個協(xié)程共享一個context

我們可以啟動多個協(xié)程,并使用同一個 context 控制它們:

func main() {
    ctx, cancel := context.WithCancel(context.Background())

    for i := 1; i <= 3; i++ {
        go func(id int) {
            for {
                select {
                case <-ctx.Done():
                    fmt.Printf("協(xié)程 %d 接收到取消信號\n", id)
                    return
                default:
                    fmt.Printf("協(xié)程 %d 正在工作\n", id)
                    time.Sleep(1 * time.Second)
                }
            }
        }(i)
    }

    time.Sleep(4 * time.Second)
    cancel()

    time.Sleep(1 * time.Second)
    fmt.Println("主程序退出")
}

輸出:

協(xié)程 1 正在工作
協(xié)程 2 正在工作
協(xié)程 3 正在工作
...(多次輸出)
協(xié)程 1 接收到取消信號
協(xié)程 2 接收到取消信號
協(xié)程 3 接收到取消信號
主程序退出

這樣我們實現(xiàn)了“一鍵終止所有協(xié)程”。

六、最佳實踐建議

  • • 永遠使用 context.WithCancel / WithTimeout 返回的 cancel() 函數(shù),不要忘記 defer cancel();
  • • 在需要可控中止的任務(如網(wǎng)絡請求、數(shù)據(jù)庫操作、循環(huán)處理)中傳入 context;
  • • 對 ctx.Done() 的監(jiān)聽要放在協(xié)程內部適當位置,防止資源泄露;
  • • 在請求鏈中傳遞 context,以實現(xiàn)鏈路級別的取消與超時控制。

七、結語

context 是 Go 并發(fā)控制中不可或缺的利器。它不僅解決了協(xié)程取消的痛點,還能為任務設置統(tǒng)一的生命周期控制邏輯,是構建高可靠網(wǎng)絡服務、后臺任務系統(tǒng)、爬蟲等并發(fā)程序的基礎設施。

如果你還沒有在項目中大量使用它,不妨從今天開始重構代碼,使用 context 管理協(xié)程生命周期,讓你的 Go 程序更穩(wěn)定、更可控!

到此這篇關于Go語言使用context控制協(xié)程取消的方法步驟的文章就介紹到這了,更多相關Go context控制協(xié)程取消內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Golang?分割字符串的實現(xiàn)示例

    Golang?分割字符串的實現(xiàn)示例

    本文主要介紹了Golang?分割字符串的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04
  • Go語言框架Beego項目搭建的方法步驟

    Go語言框架Beego項目搭建的方法步驟

    這篇文章主要介紹了Go語言框架Beego項目搭建的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-05-05
  • 詳解Go語言如何實現(xiàn)一個最簡化的協(xié)程池

    詳解Go語言如何實現(xiàn)一個最簡化的協(xié)程池

    這篇文章主要為大家詳細介紹了Go語言如何實現(xiàn)一個最簡化的協(xié)程池,文中的示例代碼講解詳細,具有一定的參考價值,有需要的小伙伴可以了解一下
    2023-10-10
  • golang利用pprof與go-torch如何做性能分析

    golang利用pprof與go-torch如何做性能分析

    這篇文章主要給大家介紹了關于golang利用pprof與go-torch如何做性能分析的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2018-07-07
  • Golang記錄、計算函數(shù)執(zhí)行耗時、運行時間的一個簡單方法

    Golang記錄、計算函數(shù)執(zhí)行耗時、運行時間的一個簡單方法

    這篇文章主要介紹了Golang記錄、計算函數(shù)執(zhí)行耗時、運行時間的一個簡單方法,本文直接給出代碼實例,需要的朋友可以參考下
    2015-07-07
  • Go語言學習之接口類型(interface)詳解

    Go語言學習之接口類型(interface)詳解

    接口是用來定義行為的類型,定義的行為不由接口直接實現(xiàn),而由通過方法由定義的類型實現(xiàn),本文就來和大家詳細講講Go語言中接口的使用吧
    2023-03-03
  • GoLang橋接模式的實現(xiàn)示例

    GoLang橋接模式的實現(xiàn)示例

    橋接模式是一種結構型設計模式,通過橋接模式可以將抽象部分和它的實現(xiàn)部分分離,本文主要介紹了GoLang橋接模式,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 使用Golang編寫一個簡單的命令行工具

    使用Golang編寫一個簡單的命令行工具

    Cobra是一個強大的開源工具,能夠幫助我們快速構建出優(yōu)雅且功能豐富的命令行應用,本文將利用Cobra編寫一個簡單的命令行工具,感興趣的可以了解下
    2023-12-12
  • Go簡單實現(xiàn)協(xié)程方法

    Go簡單實現(xiàn)協(xié)程方法

    本文主要介紹了Go簡單實現(xiàn)協(xié)程的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-12-12
  • Go中基本數(shù)據(jù)類型和字符串表示之間轉換詳解

    Go中基本數(shù)據(jù)類型和字符串表示之間轉換詳解

    這篇文章主要為大家詳細介紹了Go中基本數(shù)據(jù)類型和字符串表示之間轉換的相關知識,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2024-01-01

最新評論