可以通过context,也可以通过channel联合select取消任务
- close(channel) 是广播方法,大家都能收到。
package task_test
import (
"fmt"
"testing"
"time"
)
func isCancelled(cancelChan chan struct{}) bool {
select {
case <-cancelChan:
return true
default:
return false
}
}
func cancel_1(cancelChan chan struct{}) {
cancelChan <- struct{}{}
}
func cancel_2(cancelChan chan struct{}) {
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(cancelChan) {
break
}
time.Sleep(time.Millisecond * 5)
}
fmt.Println(i, "Done")
}(i, cancelChan)
}
cancel_2(cancelChan)
time.Sleep(time.Second * 1)
}
# 使用cancel_2 所有的任务都会被取消
# 使用cancel_1 只有一个任务会被取消
- context 也能取消任务,比channel更好用。源代码包括注释500行,值得学习
package task_test
import (
"context"
"fmt"
"testing"
"time"
)
func isCancelled(ctx context.Context) bool {
select {
case <-ctx.Done():
return true
default:
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, "Done")
}(i, ctx)
}
cancel()
time.Sleep(time.Second * 1)
}
# 所有的任务都会被取消