Go-Context与任务取消

目录

一、关联任务的取消

二、Context

1、context.WithCancel()

2、代码实现

三、总结


一、关联任务的取消

场景:当我们启动了多个子任务的同时,子任务还有子任务的时候,

如果我们只是想要取消掉一个叶子节点的任务时,那就用我上一篇文章介绍的利用 CSP, 多路选择机制和 channel 的关闭与广播就可以实现。

但是我们现在的场景是当我们取消掉父节点的任务时,想要把子节点的全部任务也一起取消掉,那该如何实现呢?

Golang从1.9以后就正式把 Context 并入Go的内置包里面了,它就是专门来做这件事儿的。

二、Context

  • 根 Context:通过 Context.Background() 创建。
  • 子 Context:context.WithCancel(parentContext)创建。

1、context.WithCancel()

ctx, cancel := context.WithCancel(context.Background())

context.WithCancel() 方法,把根节点(context.Background())传进去之后,一个是 ctx ,一个是cancel 方法,调用cancel方法则执行取消功能,而 ctx 可用传到子任务里面去,用来取消子任务,从而实现父节点和子任务都被取消掉。取消的通知形式是通过 ctx.Done() 来获得消息,从而判断是否收到通知。这个 ctx.Done() 就类比 channel 里面 close()之后,所有的channel都会收到一个通知。

2、代码实现

package cancel_by_context

import (
	"context"
	"fmt"
"sync"
"testing"
"time"
)

//任务是否已被取消
//实现原理:
//通过 ctx.Done() 接收context的消息,如果收到消息,我们就返回 true,代表任务已经被取消了
//当没有收到消息,多路选择机制就会走到 default 分支上去。
func isCanceled(ctx context.Context) bool {
	select {
	case <-ctx.Done():
		return true
	default:
		return false
	}
}

//通过context实现任务取消功能
func TestCancel(t *testing.T) {
	var wg sync.WaitGroup
	//ctx传到子节点中去,可以取消子节点,调用cancel()方法则执行取消功能
	ctx, cancel := context.WithCancel(context.Background())

	//启动 5 个协程
	for i := 0; i < 5; i++ {
		wg.Add(1)
		go func(i int, ctx context.Context, wg *sync.WaitGroup) {
			//做一个 while(true) 的循环,一直检查任务是否有被取消
			for {
				if isCanceled(ctx) {
					fmt.Println(i, "is Canceled")
					wg.Done()
					break;
				} else {
					//其它正常业务逻辑
					time.Sleep(time.Millisecond * 5)
				}
			}
		}(i, ctx, &wg)
	}
	//执行任务取消
	cancel()
	wg.Wait()
}
/*
4 is Canceled
2 is Canceled
3 is Canceled
0 is Canceled
1 is Canceled
--- PASS: TestCancel (0.00s)
PASS
*/

三、总结

  • 根 Context:通过 Context.Background() 创建。
  • 子 Context:context.WithCancel(parentContext)创建。
  • ctx.Done()用来接收消息。

:这篇博文是我学习中的总结,如有转载请注明出处:

https://blog.csdn.net/DaiChuanrong/article/details/118557199

上一篇Go-任务的取消

下一篇Go-并发任务

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值