我們已經知道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的副本,並帶有新的done
channel), 乙個是cancel函式。
當呼叫cancel函式或者parent的done
channel關閉時,新返回的done
channel就會被關閉。
例子中,呼叫cancel函式,關閉了done
channel後,進而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,或者parent
的done
channel被關閉時,
新返回的context的done
channel將被關閉。
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...