主要用Goroutine管理,停止Goroutine或之间参数传递。
上下文取消
package main import ( "context" "fmt" "time" ) func main() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() // 启动工人去干活 go worker(ctx) time.Sleep(time.Second * 5) // 告诉工人停止干活 cancel() time.Sleep(time.Second * 1) } func worker(ctx context.Context) { for { select { case <-ctx.Done(): fmt.Println("work over") return default: fmt.Println("at work") time.Sleep(time.Second * 1) } } }上下文超时
package main import ( "context" "encoding/hex" "fmt" "io/ioutil" "net/http" "time" ) type Result struct { r *http.Response err error } func main() { // 请求超时时间设置为10秒 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() res, err := httpGet(ctx) if err != nil { panic(err) } defer res.Body.Close() data, err := ioutil.ReadAll(res.Body) if err != nil { panic(err) } fmt.Println(hex.Dump(data)) } func httpGet(ctx context.Context) (*http.Response, error) { reqResult := make(chan Result, 1) go func() { res, err := http.Get("https://www.baidu.com") reqResult <- Result{res, err} }() select { case <-ctx.Done(): return nil, ctx.Err() case result := <-reqResult: return result.r, nil } }上下文截止时间
package main import ( "fmt" "golang.org/x/net/context" "time" ) func main() { ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(time.Second * 5)) defer cancel() select { case <-time.After(time.Second * 10): fmt.Println("time.After timeout") case <-ctx.Done(): // 5秒过后执行,打印:context deadline exceeded fmt.Println(ctx.Err()) } }上下文传参
package main import ( "context" "fmt" "time" ) func main() { ctx := context.WithValue(context.Background(), "id", 1) go GetID(ctx) time.Sleep(1 * time.Second) } func GetID(ctx context.Context) { id, ok := ctx.Value("id").(int) if ok { fmt.Println(id) } }