Golang併發控制 context的使用

2021-08-20 20:03:43 字數 2761 閱讀 2481

我們已經知道waitgroup可以用於併發控制,但當遇到更複雜的場景時,例如主動取消goroutine或者使超時的goroutine自動退出等,waitgroup就無能為力。

這個時候,就是context大有用武之地。

context定義了context型別,它跨api邊界和程序之間攜帶截止日期,取消訊號和其他請求範圍的值。

對伺服器的傳入請求應建立乙個context,對伺服器的傳出呼叫應接受乙個context。它們之間的函式呼叫鏈必須傳播context,或者傳遞使用withcancel,withdeadline,withtimeout或withvalue建立的派生context。當取消乙個context後,所有從這個context派生的context也會被取消。

withcancel,withdeadline和withtimeout函式接受context(父)並返回派生的context(子)和cancelfunc。呼叫cancelfunc會取消子項及其子項,刪除父項對子項的引用,並停止任何關聯的計時器。未能呼叫cancelfunc會洩漏子項及其子項,直到取消父項或計時器觸發。 go vet工具檢查cancelfuncs是否在所有控制流路徑上使用。

使用contexts的程式應遵循這些規則,以使各包之間的介面保持一致,並啟用靜態分析工具來檢查上下文傳播:

以上說明來自context包說明,如果感覺翻譯的不夠清楚,可以檢視context的說明。(實在翻譯不下去了 = =!)

context定義如下:

type context inte***ce 

err() error

value(key inte***ce{}) inte***ce{}

}

說了這麼多,現在來看下例子吧。

通過使用withcancel可以主動取消乙個或多個goroutine的執行,以實現對併發的控制。

package main 

import

("context"

"fmt"

"time"

)func

printtask

(ctx context.context)}}

func

main()

withcancel函式原型如下

func withcancel(parent context) (ctx context, cancel cancelfunc)
withcancel返回兩個結果,乙個是context(parent的副本,並帶有新的donechannel), 乙個是cancel函式。

當呼叫cancel函式或者parent的donechannel關閉時,新返回的donechannel就會被關閉。

例子中,呼叫cancel函式,關閉了donechannel後,進而printtask就會結束。

output

a man must walk down many roads.

a man must walk down many roads.

a man must walk down many roads.

main exit…

withtimeout可以實現併發超時控制,使goroutine執行超時時自動結束。

package main 

import

("context"

"fmt"

"time"

)func

main()

()select

fmt.

println

("main exit..."

)}

例子中,使用withtimeout()函式,其實現上,直接呼叫

withdeadline(parent, time.now().add(timeout))
withdeadline函式定義如下:

func withtimeout(parent context, timeout time.duration) (context, cancelfunc)
傳入引數:

返回兩個結果:

當出現超時,或者呼叫取消函式cancel,或者parentdonechannel被關閉時,

新返回的context的donechannel將被關閉。

output:

context deadline exceeded

main exit…

golang context學習記錄1

golang context學習記錄2

golang併發控制方法WaitGroup

1.waitgroup的作用 waitgroup是golang併發的兩種方式之一,乙個是channel,另乙個是waitgroup。waitgroup的api只有3個,非常簡單好用,但是有各種坑。2.waitgroup的用法 waitgroup有3個api 1 add delta int 增加 減少...

golang 閒談併發

對於併發這個概念,我想大家都對它不會陌生,今天就從簡單的火車站賣票問題出發,來談談併發。首先宣告本文的 是golang 因為最近開始用的就是golang 對於其他的語言其實也是相通的,那麼正式開始正題吧,首先我們來看看,賣一張票,總票數就減一,一般來說我們會這麼寫 package main impo...

golang 併發實踐

golang 高併發主要是依靠sync包下的api實現,首先就是waitgroup 先說說waitgroup的用途 它能夠一直等到所有的goroutine執行完成,並且阻塞主線程的執行,直到所有的goroutine執行完成。waitgroup總共有三個方法 add delta int done wa...