type Context interface {
Deadline() (deadline time.Time, ok bool)
Done() <-chan struct{}
Err() error
Value(key interface{}) interface{}
}
Context接口包含四個方法:
- Deadline返回綁定當前context的任務被取消的截止時間庭呜;如果沒有設定期限,將返回ok == false。
- Done 當綁定當前context的任務被取消時峡碉,將返回一個關閉的channel鲫寄;如果當前context不會被取消吉执,將返回nil地来。
- Err 如果Done返回的channel沒有關閉,將返回nil;如果Done返回的channel已經(jīng)關閉咕宿,將返回非空的值表示任務結束的原因蜡秽。如果是context被取消,Err將返回Canceled芽突;如果是context超時,Err將返回DeadlineExceeded寞蚌。
- Value 返回context存儲的鍵值對中當前key對應的值,如果沒有對應的key,則返回nil壹哺。
父節(jié)點Context可以主動通過調(diào)用cancel方法取消子節(jié)點Context艘刚,而子節(jié)點Context只能被動等待。同時父節(jié)點Context自身一旦被取消(如其上級節(jié)點Cancel),其下的所有子節(jié)點Context均會自動被取消笛臣。
有三種創(chuàng)建方法:
// 帶cancel返回值的Context隧饼,一旦cancel被調(diào)用,即取消該創(chuàng)建的context
func WithCancel(parent Context) (ctx Context, cancel CancelFunc)
// 帶有效期cancel返回值的Context燕雁,即必須到達指定時間點調(diào)用的cancel方法才會被執(zhí)行
func WithDeadline(parent Context, deadline time.Time) (Context, CancelFunc)
// 帶超時時間cancel返回值的Context,類似Deadline僧免,前者是時間點捏浊,后者為時間間隔
// 相當于WithDeadline(parent, time.Now().Add(timeout)).
func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)
package main
import (
"context"
"fmt"
"log"
"os"
"time"
)
var logg *log.Logger
func someHandler() {
//ctx, cancel := context.WithCancel(context.Background())
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(5*time.Second))
go doStuff(ctx) //這個協(xié)程有5s的超時時間限制
//10秒后取消doStuff
time.Sleep(30 * time.Second)
logg.Printf("wait")
cancel() // cancel被調(diào)用,即取消該創(chuàng)建的ctx
}
//每1秒work一下浊洞,同時會判斷ctx是否被取消了,如果是就退出
func doStuff(ctx context.Context) {
for {
time.Sleep(1 * time.Second)
select {
case <-ctx.Done():
logg.Printf("done")
return
default:
logg.Printf("work")
}
}
}
func main() {
logg = log.New(os.Stdout, "", log.Ltime)
someHandler()
logg.Printf("down")
}
以上執(zhí)行結果:可以看出doStuff在5s之后執(zhí)行結束(超時時間限制)法希,context的cancel是在30s之后