context包的withtimout
这里讨论复用context的情况
package main
import (
"context"
"fmt"
"time"
)
func main() {
// 传递带超时的上下文告诉阻塞函数
// 超时过后应该放弃它的工作。
ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond)
defer cancel()
f := func(ctx context.Context, tsMill int) {
select {
case <-time.After(time.Duration(tsMill) * time.Millisecond):
fmt.Println("func timeout", tsMill)
case <-ctx.Done():
fmt.Println(ctx.Err()) // 打印"context deadline exceeded"
}
}
f(ctx, 25)
f(ctx, 30)
fmt.Println("main end")
}
package main
import (
"context"
"fmt"
"time"
)
func f1(ctx context.Context) {
t := time.NewTicker(time.Duration(time.Second * 2))
select {
case <-t.C:
fmt.Println("f1 tick", time.Now())
return
case <-ctx.Done():
fmt.Println("f1 ctx.Done")
}
}
func f2(ctx context.Context) {
t := time.NewTicker(time.Duration(time.Second * 3))
select {
case <-t.C:
fmt.Println("f2 tick", time.Now())
return
case <-ctx.Done():
fmt.Println("f2 ctx.Done", time.Now())
}
}
func main() {
fmt.Println("main begin", time.Now())
ctx, cancel := context.WithTimeout(context.Background(), time.Second*4)
defer func() {
cancel()
fmt.Println("cancel()", time.Now())
}()
f1(ctx)
f2(ctx)
fmt.Println("main end", time.Now())
}
结果
[root@localhost d0831]# go run main.go
main begin 2021-09-01 07:43:23.27511909 +0800 CST m=+0.000206196
f1 tick 2021-09-01 07:43:25.276065643 +0800 CST m=+2.001152697
f2 ctx.Done 2021-09-01 07:43:27.276073332 +0800 CST m=+4.001160388
main end 2021-09-01 07:43:27.276106832 +0800 CST m=+4.001193875
cancel() 2021-09-01 07:43:27.276113528 +0800 CST m=+4.001200561
可以看到,复用timeout的ctx是会减的,后者使用剩余的时间

浙公网安备 33010602011771号