学习笔记,写到哪是哪。
最近看了看go语言Context的使用,觉着很神奇也很便捷。
说到context,我在学习golang的时候看到很多库都用到了,简而言之,context可以处理多个goroutine之间的交互问题。类比于其他语言,你可能需要自己定义一个线程安全对象,通过线程安全对象来实现多个线程间的交互操作。golang直接有个默认包context,可以省掉每次定义的过程,还是很方便的。
具体关于Context的使用,我就不细说了,网上很多。
本文主要将我用context来实现一种超时场景的处理。
先使用context.WithTimeout方法来实现超时处理。
代码如下:
- package main
-
- import (
- "context"
- "fmt"
- "time"
- )
-
- func handle() {
- //构建超时上下文
- _ctx, _cancel := context.WithTimeout(context.Background(), 5*time.Second)
- go work(_ctx)
- time.Sleep(6 * time.Second)
- _cancel()
- }
-
-
- //工作
- func work(ctx context.Context) {
- for {
- time.Sleep(1 * time.Second)
- select {
- case <-ctx.Done():
- fmt.Println("work done")
- default:
- fmt.Println("working")
- }
- }
- }
-
-
- func main() {
- handle()
- }
代码说明
1、 构建一个5秒超时的上下文传入goroutine,work方法轮询上下文状态。
执行结果
先使用context.WithDeadline方法来实现超时处理。
代码如下:
- package main
-
- import (
- "context"
- "fmt"
- "time"
- )
-
-
- func handle1() {
- //构建超时上下文
- _ctx, _cancel := context.WithDeadline(context.Background(), time.Now().Add(5*time.Second))
- go work1(_ctx)
- time.Sleep(6 * time.Second)
- _cancel()
- }
-
- //工作1
- func work1(ctx context.Context) {
- for {
- time.Sleep(1 * time.Second)
- if _deadline, _a := ctx.Deadline(); _a {
- if time.Now().After(_deadline) {
- fmt.Println("after deadline")
- break
- }
- }
- select {
- case <-ctx.Done():
- fmt.Println("work done")
- default:
- fmt.Println("working")
- }
- }
- }
-
- func main() {
- handle1()
- }
代码说明
1、注意WithDeadline后面的时间参数方式,和WithTimeout不同。
2、这里在轮训前判断一下是否当前时间已经超过deadline,如果超过了直接跳出。
执行结果
context还有很多用法,需要在项目中多使用,以后分享更多感受。