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)