go协程上下文context
context
context1.17
上下文解决的问题
- 协程间的通信
channel
contextcontext.withvalue()channel
- 子协程的超时处理
context
上下文的几个方法和用法
context.withcancel(context.context)
withcancel()context.background()cancal()
package main import ( "context" "fmt" "time" ) func worker(ctx context.context) { for { select { case <-ctx.done(): return default: } fmt.println("worker...") time.sleep(time.second * 1) } } func main() { ctx, cancal := context.withcancel(context.background()) go worker(ctx) time.sleep(time.second * 5) cancal() fmt.println("over ...") }
context.withtimeout(context.context,timeout)
cancel()cancel()
package main import ( "context" "fmt" "time" ) func worker(ctx context.context) { for { select { case <-ctx.done(): return default: } fmt.println("worker...") time.sleep(time.second * 1) } } func main() { ctx, cancal := context.withtimeout(context.background(), time.second*2) go worker(ctx) time.sleep(time.second * 5) cancal() fmt.println("over ...") }
context.withdeadline(context.context,(绝对时间)timeout)
timeoutcancel()cancel()
package main import ( "context" "fmt" "time" ) func worker(ctx context.context) { for { select { case <-ctx.done(): return default: } fmt.println("worker...") time.sleep(time.second * 1) } } func main() { ctx, cancal := context.withdeadline(context.background(), time.now().add(3 * time.second)) go worker(ctx) time.sleep(time.second * 5) cancal() fmt.println("over ...") }
context.withvalue()
先看一下这段代码
package main import ( "context" "fmt" "time" ) type ctxkey string func worker(ctx context.context) { // 在子协程中获取上下文信息 num, ok := ctx.value(ctxkey("num")).(string) if !ok { fmt.println("invalid trace code") } fmt.println(num) for { select { case <-ctx.done(): return default: } fmt.println("worker...") time.sleep(time.second * 1) } } func main() { ctx, cancal := context.withdeadline(context.background(), time.now().add(3*time.second)) // 利用上下文传一个 num = 1234567 // 实例化一个上下文 ctx = context.withvalue(ctx, ctxkey("num"), "1234567") go worker(ctx) time.sleep(time.second * 5) cancal() fmt.println("over ...") }
通过上下文实现协程间的通信,如果项目大,为了避免变量的污染,原则上:上下文通信所用的key需要自定义一个类型
type tracecode string;context.withvalue(context.context,key,value)