Context上下文包套路入门(1)

context包被称为上下文包,go 1.7加入,用于协程之间的上下文数据的传递、中止核控制超时。

在网络编程中可用于请求的中止,比如服务访问链的中止:a用户注册->b调用用户服务->c调用积分服务
其中a调用b,b调用c。如果由于a和b之间因为某些原因被取消或者超时了,那么b和c之间也要取消。

Context接口源码解读:

type Context interface{
	//返回一个超时时间
	Deadline()(deadline time.Time, ok bool)
	//返回只读channel
	//一旦可读,代表父context发起取消操作,通过该方法可以收到此信号
	//完成协程退出并返回Err()
	Done()<-chan struct{}
	//返回context被取消的原因
	Err() error
	//获取Context上绑定值(根据key),线程安全
	Value(key interface{}) interface{}
}

空上下文

在进行上下文控制之前,首先要创建一个顶层context。
go内置包提供了一个方法:

context.Background()

WithTimeout超时自动取消

当执行一个go协程时,超时自动取消协程

package main

import (
	"context"
	"fmt"
	"time"
)

// 模拟一个最小执行时间的阻塞函数
func incr(a int) int {
	res := a + 1
	time.Sleep(time.Second * 1)
	return res
}

// 提供一个阻塞接口
// 计算a+b,注意a,b不能是负数
// 如果计算被中断,则返回-1
func Add(ctx context.Context, a, b int) int {
	fmt.Printf("开始")

	res := 0
	for i := 0; i < a; i++ {
		res = incr(res)
		select {
		case <-ctx.Done(): //父context超时了
			return -1

		}
	}
	for i := 0; i < b; i++ {
		res = incr(res)
		select {
		case <-ctx.Done(): //父context超时了
			return -1

		}
	}

	return res
}

func main() {
	ctx, _ := context.WithTimeout(context.Background(), time.Second*2)
	res := Add(ctx, 1, 2)
	fmt.Println(res)	//-1
}

WithCancel 手动取消方法

func main() {
	ctx, cancel := context.WithCancel(context.Background())
	go func() {
		time.Sleep(time.Second * 2)
		cancel() //在调用处主动取消
	}()
	res := Add(ctx, 1, 2)
	fmt.Println(res) //-1
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值