当前位置: 代码迷 >> 综合 >> cancel--任务取消的机制
  详细解决方案

cancel--任务取消的机制

热度:51   发布时间:2023-12-25 07:25:52.0

协程的cancel

    • close版本
    • context 版本

close版本

package ch20import ("fmt""testing""time"
)
//任务的取消 使用多路复用和通道关闭的广播机制func isCancelled(cancelChan chan struct{
    }) bool {
    select {
    //收到消息就是被取消了,没收到消息就代表还没被取消case <- cancelChan:return truedefault:return false}
}
func cancel_1(cancelChan chan struct{
    })  {
    //发送了一个空结构,没有意义//发现只有一个任务被Cancel掉了cancelChan <- struct{
    }{
    }//这样编写程序耦合太多,取消所有的GoRuntine
}
func cancel_2(cancelChan chan struct{
    })  {
    //自带广播的关闭机制//广播机制,所有的协程都受到了channel的信号,所有都被cancel了close(cancelChan)
}func TestCancel(t *testing.T)  {
    cancelChan := make(chan struct{
    },0)for i:=0;i<5;i++{
    go func(i int,cancelCh chan struct{
    }) {
    for{
    if isCancelled(cancelCh){
    break}time.Sleep(time.Millisecond *5)}fmt.Println(i,"Cancel")}(i,cancelChan)}cancel_2(cancelChan)time.Sleep(time.Second*1)
}

context 版本

package contextimport ("context""fmt""testing""time"
)//取消关联任务
//取消叶子节点的子任务 直接取消掉就好 取消中间的子任务 就需要取消全部的它的子任务
// 1.9之后 Context进入了golang内置的包//根Context 通过context.Background()创建
//子Context context.WithCancel(parentContext)创建
//ctx,cancel = context.WithCancel(context.Background()) cancel方法作为返回值
//当前Context被取消时,基于他的子context都会被取消
//接受取消通知 <-ctx.Done()func isCancelled(ctx context.Context) bool {
    select {
    //收到消息就是被取消了,没收到消息就代表还没被取消case <- ctx.Done():return truedefault:return false}
}func TestCancel(t *testing.T)  {
    ctx,cancel:= context.WithCancel(context.Background())for i:=0;i<5;i++{
    go func(i int,ctx context.Context) {
    for{
    if isCancelled(ctx){
    break}time.Sleep(time.Millisecond *5)}fmt.Println(i,"Cancel")}(i,ctx)}cancel()time.Sleep(time.Second*1)
}