Go 学习笔记- 基础篇11 context 并发控制
context 包是 go 1.7 是引入的,可以方便的对请求做取消和超时控制 在GoWeb 编程中,在处理浏览器请求时,通常要调用数据库,上游接口,等等, 如果请求断开,可以使用 context, 来取消一系列的动作避免资源 空转, 下图是go Context 的结构体方法type Context interface { Deadline() (deadline time.Time, ok bool) Done() <-chanstruct{} Err() error Value(key interface{}) interface{}}使用context 首先需要创建一个context ,使用context.Background()就可以,context 创建后,不可以修改,但可以派生,比如基于第一个context 再创建一个 , context.WithTimeout(ctx, 2* time.Second),这样就派生出一个 2s 后超时的context 了,把可个context 绑定在请求上,就可以实现 请求的超时控制,下面是代码:首先 需要创建一个可以取消的的 context , 这次是 context.WithCancel(), 这个Api 有两个返回值,一个是 ctx, 一个是cancel 调用cancel会给 goroutine 一个通知,其实是一个通道消息,结合之前 讲的 for ... select 语句,就可以结束 goroutine 的运行把上面的例子 稍微改一下,就可以,Api 是 context.WithValue注意这里使用了 我们上一篇讲的类型断言,因为从context 中取出的值是一个 any 类型,我们需要使用类型断言取到正确的类型1. context 创建后,不要放在结构体中,应该做为函数的第一个参数传递2. 不要用 context.WithValue 来替代函数的参数,这个值一般是用于用于请求范围的数据(如 auth token, trace ID)3. 及时调用 cancel 函数:对于 WithCancel, WithTimeout, WithDeadline 创建的 context,必须调用返回的 cancel 函数以释放内部资源(即使已经超时)。通常使用 defer cancel()。使用之前先创建,withTimeout, withDeadline withCancel来派生,withValue 要慎重, context 其实是一个 函数执行的控制器