go并发-任务启动和取消

Posted 文大侠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了go并发-任务启动和取消相关的知识,希望对你有一定的参考价值。

目录

1.借助chan自定义取消

2.context取消


并发编程中,常会遇到任务启动后取消控制问题,这里两种方法实现

1.借助chan自定义取消

这里借助select多路选择的default分支判断是否任务取消,如下isCanceled实现,在Cancel调用时关闭chan通道,会触发返回true。

type CancelTask struct {
	sync chan int
	wg   *sync.WaitGroup
}

func NewCancelTask() *CancelTask {
	return &CancelTask{make(chan int), &sync.WaitGroup{}}
}

func (t *CancelTask) Start(taskid int) {
	fmt.Printf("Task %v start\\n", taskid)

	// 开启任务
	t.wg.Add(1)
	go func() {
		for {
			if t.isCanceld() {
				fmt.Printf("Task %v Stop Done!\\n", taskid)
				break
			} else {
				fmt.Printf("Task %v Running... \\n", taskid)
				time.Sleep(time.Second * 3)
			}
		}

		t.wg.Done()
	}()
}

func (t *CancelTask) Cancel() {
	fmt.Printf("Task stopping...\\n")
	close(t.sync)

	t.wg.Wait()
}

func (t *CancelTask) isCanceld() bool {
	select {
	case <-t.sync:
		return true
	default: //不取消控制
		return false
	}
}

func TestCancelTask(t *testing.T) {
	task := NewCancelTask()

	task.Start(1)
	task.Start(2)
	task.Start(3)

	time.Sleep(time.Second * 5)
	task.Cancel()
}

2.context取消

go 官方支持context取消控制,上述程序可改写如下,只是isCanceled实现有变化。

type CancelTask2 struct {
	ctx    context.Context
	cancel context.CancelFunc

	wg *sync.WaitGroup
}

func NewCancelTask2() *CancelTask2 {
	ctx, cancel := context.WithCancel(context.Background())
	return &CancelTask2{ctx, cancel, &sync.WaitGroup{}}
}

func (t *CancelTask2) Start(taskid int) {
	fmt.Printf("Task %v start\\n", taskid)

	// 开启任务
	t.wg.Add(1)
	go func() {
		for {
			if t.isCanceld() {
				fmt.Printf("Task %v Stop Done!\\n", taskid)
				break
			} else {
				fmt.Printf("Task %v Running... \\n", taskid)
				time.Sleep(time.Second * 3)
			}
		}

		t.wg.Done()
	}()
}

func (t *CancelTask2) Cancel() {
	fmt.Printf("Task stopping...\\n")
	t.cancel()

	t.wg.Wait()
}

func (t *CancelTask2) isCanceld() bool {
	select {
	case <-t.ctx.Done():
		return true
	default: // 不取消
		return false
	}
}

func TestCancelTask2(t *testing.T) {
	task := NewCancelTask2()

	task.Start(1)
	task.Start(2)
	task.Start(3)

	time.Sleep(time.Second * 5)
	task.Cancel()
}

 原创,转载请注明来自

以上是关于go并发-任务启动和取消的主要内容,如果未能解决你的问题,请参考以下文章

go并发-任务启动和取消

《Java并发编程实战》---- 取消与关闭

Go并发模式:管道与取消

Java并发编程学习12-任务取消(上)

Java并发编程学习12-任务取消(上)

Go基础--goroutine和channel