关键代码实现
- 定义任务结构体:
type Task struct {
name string
ctx context.Context
cancel context.CancelFunc
log *sync.Map
}
- 创建任务函数:
func NewTask(name string, parentCtx context.Context) *Task {
ctx, cancel := context.WithCancel(parentCtx)
return &Task{
name: name,
ctx: ctx,
cancel: cancel,
log: &sync.Map{},
}
}
- 执行任务函数:
func (t *Task) Execute() {
defer t.cancel()
select {
case <-t.ctx.Done():
t.log.Store("status", "cancelled")
return
default:
// 实际任务逻辑
t.log.Store("status", "completed")
}
}
- 上层任务管理:
func main() {
rootCtx, rootCancel := context.WithCancel(context.Background())
defer rootCancel()
rootTask := NewTask("rootTask", rootCtx)
subTask1 := NewTask("subTask1", rootTask.ctx)
subTask2 := NewTask("subTask2", rootTask.ctx)
go subTask1.Execute()
go subTask2.Execute()
// 模拟条件取消
go func() {
// 满足某个条件
rootCancel()
}()
time.Sleep(time.Second)
}
注意点
- Context传递:在创建子任务时,务必使用父任务的context来创建新的context,确保取消信号能正确传递。
- 取消处理:每个任务在执行时要及时检查context的取消信号,一旦收到取消信号,应立即停止任务并记录相应状态。
- 日志记录:使用
sync.Map
来保证在并发环境下日志记录的安全性,不同任务对日志的读写操作不会产生冲突。
- 资源清理:在任务取消时,要确保所有相关资源(如文件句柄、网络连接等)都能正确释放。