go context学习
context学习
- context的struct设计
type Context interface {
Deadline() (deadline time.Time, ok bool)
Done() <-chan struct{}
Err() error
Value(key interface{}) interface{}
}
-
struct中字段分析
- Deadline()返回设置的截止时间和有无设置截止时间
- Done()返回一个只读的chan,用来通知是否要释放资源
- Err()返回取消的原因
- Value(key interface{})获取绑定在context上的值,是一个键值对。这个值是线程安全的。(在并发情况下,能够正确处理这个共享变量)
-
context的常用方法实例
- 参考代码
package main
import(
"fmt"
"time"
"golang.org/x/net/context"
)
type faveContextKey string //定义别名
func main(){
fmt.Println("context包学习")
UseContext()
UseContextWithDeadline()
UseContextWithTimeout()
UseContextWithValue()
}
func UseContext(){
// 使用withCancel生成上下文
gen := func (ctx context.Context)<- chan int{
dst := make(chan int) //无缓冲,无长度
n := 1
fmt.Println("这个函数被调用多少次:",n) //被调用一次
go func (){
for{
select{
// 多个case同时满足,就会随机执行case
case <- ctx.Done():
// 关闭上下文
fmt.Println("ctx.Done",ctx.Err(),n)
return
case dst <- n: //要么运行完这个作用域,要么就不用运行
n++
fmt.Printf("n = %v \n",n)
}
}
}()
//发送器
return dst
}
ctx,cancel := context.WithCancel(context.Background())
defer cancel()
data := gen(ctx)
for n:= range data{ //接收
fmt.Println(n)
if n== 16{
break
}
}
}
func UseContextWithDeadline(){
// withDeadline作用:设置context的存活期
d := time.Now().Add(50 * time.Millisecond)
ctx,cancel := context.WithDeadline(context.Background(),d)
if ctx == nil{
fmt.Println("ctx is nil")
return
}
defer cancel()
select{
case <-time.After(time.Second*1):
fmt.Println("overslept")
case <- ctx.Done():
fmt.Println(ctx.Err())
}
}
func UseContextWithTimeout(){
// withTimeout作用:设置context的存活期
ctx,cancel := context.WithTimeout(context.Background(),50*time.Millisecond)
if ctx == nil{
fmt.Println("ctx is nil")
return
}
defer cancel()
select{
case <-time.After(time.Second*1):
fmt.Println("overslept")
case <- ctx.Done():
fmt.Println(ctx.Err())
}
}
func UseContextWithValue(){
// withValue作用:带值
f := func(ctx context.Context,k faveContextKey){
if v := ctx.Value(k);v!=nil{
fmt.Printf("key:%v,value:%v \n",k,v)
}else{
fmt.Println("key not found!",k)
}
}
k := faveContextKey("language")
ctx:= context.WithValue(context.Background(),k,"go")
if ctx==nil{
fmt.Println("ctx is nil")
}
f(ctx,k)
f(ctx,faveContextKey("color"))
}
-
context包的用途
- 构建树形关系的上下文,实现上一层的Goruntine控制下一层的Goruntine。通过传递context的对象变量方式对下一层的Goruntine进行管控。通知信号为context对象中的Done()进行控制。
- 参考用例
-
帮助理解的博客,(侵权,请告知,我会删了的)
-
写的不好的地方可以,加微信讨论一下。谢谢