Go語言中通過context包實現(xiàn)并發(fā)任務(wù)取消,最常用方式是將context.Context作為參數(shù)傳遞給并發(fā)函數(shù),并在任務(wù)中監(jiān)聽其Done通道以響應(yīng)取消信號。示例中l(wèi)ongRunningTask函數(shù)通過select監(jiān)聽ctx.Done(),當(dāng)調(diào)用cancel()或超時觸發(fā)時,任務(wù)打印取消信息并退出??墒褂胏ontext.WithCancel手動取消、WithTimeout設(shè)置超時自動取消、WithDeadline設(shè)定截止時間。context支持鏈?zhǔn)絺鞑ィ嫌稳∠麜ㄖ掠嗡信缮鷆ontext,Go 1.20+還可通過WithCancelCause傳遞取消原因。為避免goroutine泄漏,應(yīng)在所有并發(fā)函數(shù)中定期檢查context狀態(tài),并及時釋放資源。
在Go語言中實現(xiàn)并發(fā)任務(wù)取消機(jī)制,最常用的方式是通過 context 包。它能安全地跨goroutine傳遞取消信號、超時和截止時間,是控制并發(fā)任務(wù)生命周期的標(biāo)準(zhǔn)做法。
每個需要支持取消的并發(fā)任務(wù)都應(yīng)該接收一個 context.Context 參數(shù)。當(dāng)外部觸發(fā)取消時,所有監(jiān)聽該context的goroutine都能收到通知并主動退出。
示例代碼:package main <p>import ( "context" "fmt" "time" )</p><p>func longRunningTask(ctx context.Context) { for { select { case <-ctx.Done(): fmt.Println("任務(wù)被取消:", ctx.Err()) return default: fmt.Println("任務(wù)正在運(yùn)行...") time.Sleep(500 * time.Millisecond) } } }</p><p>func main() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() // 確保釋放資源</p><pre class="brush:php;toolbar:false;"><pre class="brush:php;toolbar:false;">go longRunningTask(ctx) // 模擬運(yùn)行一段時間后取消 time.Sleep(2 * time.Second) cancel() // 給取消留出處理時間 time.Sleep(1 * time.Second)
}
除了手動調(diào)用 cancel(),還可以設(shè)置超時時間,讓任務(wù)在指定時間內(nèi)未完成時自動取消。
立即學(xué)習(xí)“go語言免費(fèi)學(xué)習(xí)筆記(深入)”;
<pre class="brush:php;toolbar:false;">// 3秒后自動取消 ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() <p>go longRunningTask(ctx)</p><p>// 不需要手動調(diào)用cancel,超時后自動觸發(fā) time.Sleep(4 * time.Second)</p>
如果你希望任務(wù)在某個具體時間點(diǎn)前結(jié)束,可以用 context.WithDeadline。
<pre class="brush:php;toolbar:false;">deadline := time.Now().Add(5 * time.Second) ctx, cancel := context.WithDeadline(context.Background(), deadline) defer cancel() <p>go longRunningTask(ctx)</p>
context支持鏈?zhǔn)絺鬟f,上游取消會觸發(fā)下游全部取消。你也可以用 context.WithCancelCause(Go 1.20+)傳遞取消原因。
多個條件取消可以通過 select 監(jiān)聽多個channel實現(xiàn),比如同時監(jiān)聽用戶取消和系統(tǒng)中斷信號。
<pre class="brush:php;toolbar:false;">ctx, cancel := context.WithCancel(context.Background()) <p>// 監(jiān)聽系統(tǒng)中斷信號 go func() { signalChan := make(chan os.Signal, 1) signal.Notify(signalChan, os.Interrupt) <-signalChan cancel() }()</p>
基本上就這些。關(guān)鍵是把context作為第一個參數(shù)傳給所有可能并發(fā)執(zhí)行的函數(shù),并在循環(huán)或阻塞操作中定期檢查它的Done通道。這樣能確保任務(wù)及時響應(yīng)取消,避免goroutine泄漏。
以上就是如何使用Golang實現(xiàn)并發(fā)任務(wù)取消機(jī)制的詳細(xì)內(nèi)容,更多請關(guān)注php中文網(wǎng)其它相關(guān)文章!
每個人都需要一臺速度更快、更穩(wěn)定的 PC。隨著時間的推移,垃圾文件、舊注冊表數(shù)據(jù)和不必要的后臺進(jìn)程會占用資源并降低性能。幸運(yùn)的是,許多工具可以讓 Windows 保持平穩(wěn)運(yùn)行。
微信掃碼
關(guān)注PHP中文網(wǎng)服務(wù)號
QQ掃碼
加入技術(shù)交流群
Copyright 2014-2025 http://ipnx.cn/ All Rights Reserved | php.cn | 湘ICP備2023035733號