Context应用场景
Context取消goroutine任务
context.Withcancel
返回一个 cancel
函数,调用 cancel
函数的时候,会触发 context.Done()
函数
package main
import (
"context"
"fmt"
"time"
)
func demo(ctx context.Context) {
for {
time.Sleep(time.Second * 1)
select {
case <- ctx.Done():
fmt.Println("done")
return
default:
fmt.Println("work")
}
}
}
func main() {
ctx, cancelFunc := context.WithCancel(context.Background())
go demo(ctx)
time.Sleep(time.Second * 10)
cancelFunc()
}
原理:调用
cancelFunc
相当于往一个无缓冲的channel
中写入一条数据,ctx.Done()
当读到数据时则推出goroutine
Context进行超时控制
context.WithTimeout
超过指定时间之后,会触发 context.Done
函数
package main
import (
"context"
"fmt"
"time"
)
func demo(ctx context.Context) {
for {
time.Sleep(time.Second * 1)
select {
case <- ctx.Done():
fmt.Println("done")
return
default:
fmt.Println("work")
}
}
}
func main() {
ctx, cancelFunc := context.WithDeadline(context.Background(), time.Now().Add(time.Second*5))
go demo(ctx)
time.Sleep(time.Second * 10)
cancelFunc()
}
WithTimeout
效果与 WithDeadline
相同,只是传入的时间参数不同。
package main
import (
"context"
"fmt"
"time"
)
func demo(ctx context.Context) {
for {
time.Sleep(time.Second * 1)
select {
case <- ctx.Done():
fmt.Println("done")
return
default:
fmt.Println("work")
}
}
}
func main() {
ctx, cancelFunc := context.WithTimeout(context.Background(), time.Second * 5)
go demo(ctx)
time.Sleep(time.Second * 10)
cancelFunc()
}
Context传递通用参数
context.WithValue(ctx, "key", value)
把参数设置到 context
中
context.Value("key")
获取参数
package main
import (
"context"
"fmt"
"time"
)
func main() {
ctx := context.WithValue(context.Background(), "name", "111")
go g1(ctx)
time.Sleep(time.Second * 1)
}
func g1(ctx context.Context) {
fmt.Println(ctx.Value("name"))
fmt.Println("222")
go g2(context.WithValue(ctx, "name", "444"))
}
func g2(ctx context.Context) {
fmt.Println("333")
fmt.Println(ctx.Value("name"))
}