import "context"!
view context package source code!
see example code for a server that uses contexts!
view golang documentation about context!
假設你需要制作一個三明治,于是你安排了三個人分別去買番茄、面包和火腿,買火腿的人到了超市后發現沒有火腿了,于是叫超市的店員給他現場制作一個火腿,買面包和番茄的人分別在去面包店和番茄店的路上,
這時你突然決定不吃火腿了,為了不浪費資源,我們需要有一個機制,可以讓制作火腿的人停止制作火腿,去超市的人立刻停止去超市,等火腿的人立刻停止等火腿,
自定義一個函式sleepAndTalk() -
func sleepAndTalk(ctx context.Context, d time.Duration, msg string) {
select {
case <- time.After(d)
fmt.Println(msg)
case <- ctx.Done()
log.Print(ctx.Err())
}
}
取消 -
func main() {
ctx := Context.Background()
ctx, cancel := context.WithCancel(ctx)
go func () {
s := bufio.NewScanner(os.Stdin)
s.Scan()
cancel()
}()
sleepAndTalk(ctx, 5 * time.Second, "Hello")
}
用go run *.go運行上面的代碼,如果沒有Stdin,則5秒后輸出Hello,如果在5秒內有Stdin,則可以立即cancel將會運行的sleepAndTalk(),
func main() {
ctx := Context.Background()
ctx, cancel := context.WithCancel(ctx)
go func () {
time.Sleep(time.Second)
cancel()
}()
sleepAndTalk(ctx, 5 * time.Second, "Hello")
}
Cancel() after 1 second. The code above is equivalent to -
func main() {
ctx := Context.Background()
ctx, cancel := context.WithCancel(ctx)
time.AfterFunc(time.Second, cancel)
sleepAndTalk(ctx, 5 * time.Second, "Hello")
}
or -
func main() {
ctx := Context.Background()
ctx, cancel := context.WithTimeout(ctx, time.Second)
cancel() // release resources for timer
sleepAndTalk(ctx, 5 * time.Second, "Hello")
}
Methods that handle cancelations -
Background()
WithCancel()
WithTimeout()
WithDeadline()
使用通道和選擇
func main() {
stop := make(chan bool)
go func() {
for {
select {
case <- stop: // 在channel收到值后輸出stop并回傳
fmt.Println("stop!")
return
default: // 在channel收到任何bool之前一直會跑default
fmt.Println("running...")
time.Sleep(1 * time.Second)
}
}
}()
time.Sleep(5 * time.Second)
fmt.Println("sending value to channel \"stop\"")
stop <- true
time.Sleep(5 * time.Second)
}
通道和選擇無法處理復雜的執行緒樹,
背景關系可以嗎?
func main() {
// Background() is the root Context
// WithCancel() add a new Context node
ctx, cancel := context.WithCancel(context.Background())
go func() {
for {
select {
case <- ctx.Done(): // Done()在參考cancel()之后打開channel
fmt.Println("stop!")
return
default: // 在channel收到任何bool之前一直會跑default
fmt.Println("running...")
time.Sleep(1 * time.Second)
}
}
}()
time.Sleep(5 * time.Second)
fmt.Println("sending value to channel \"stop\"")
cancel()
time.Sleep(5 * time.Second)
}
多個執行緒的例子 -
func main() {
ctx, cancel := context.WithCancel(context.Background())
go worker(ctx, node1)
go worker(ctx, node2)
go worker(ctx, node3)
time.Sleep(5 * time.Second)
fmt.Println("sending value to channel \"stop\"")
cancel()
time.Sleep(5 * time.Second)
}
func worker(ctx context.Context, name string) {
go func() {
for {
select {
case <- ctx.Done(): // Done()在參考cancel()之后打開channel
fmt.Println(name, "stop!")
return
default: // 在channel收到任何bool之前一直會跑default
fmt.Println(name, "running...")
time.Sleep(1 * time.Second)
}
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/250730.html
標籤:區塊鏈
上一篇:機器人量化交易現成原始碼
下一篇:[Tesseract報錯及解決方法]Error in findFileFormat: image file not found
