go并发-任务启动和取消
Posted 文大侠
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了go并发-任务启动和取消相关的知识,希望对你有一定的参考价值。
目录
并发编程中,常会遇到任务启动后取消控制问题,这里两种方法实现
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并发-任务启动和取消的主要内容,如果未能解决你的问题,请参考以下文章