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 &CancelTaskmake(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 &CancelTask2ctx, 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并发-任务启动和取消

Go协程并发信道

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

Go并发模式:管道与取消

Go基础--goroutine和channel

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