MST

星途 面试题库

面试题:Go批处理任务中context的复杂场景应用

在一个具有复杂依赖关系的批处理任务系统中,有多个层级的子任务调用。上层任务可能因为某些条件取消,并且要求所有依赖的下层子任务也能正确响应取消信号。同时,每个子任务执行过程中需要记录执行状态到共享的日志系统。请设计一个基于Go语言和context的解决方案,并阐述关键代码实现和注意点。
14.2万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

关键代码实现

  1. 定义任务结构体
type Task struct {
    name string
    ctx  context.Context
    cancel context.CancelFunc
    log  *sync.Map
}
  1. 创建任务函数
func NewTask(name string, parentCtx context.Context) *Task {
    ctx, cancel := context.WithCancel(parentCtx)
    return &Task{
        name: name,
        ctx:  ctx,
        cancel: cancel,
        log: &sync.Map{},
    }
}
  1. 执行任务函数
func (t *Task) Execute() {
    defer t.cancel()
    select {
    case <-t.ctx.Done():
        t.log.Store("status", "cancelled")
        return
    default:
        // 实际任务逻辑
        t.log.Store("status", "completed")
    }
}
  1. 上层任务管理
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)
}

注意点

  1. Context传递:在创建子任务时,务必使用父任务的context来创建新的context,确保取消信号能正确传递。
  2. 取消处理:每个任务在执行时要及时检查context的取消信号,一旦收到取消信号,应立即停止任务并记录相应状态。
  3. 日志记录:使用sync.Map来保证在并发环境下日志记录的安全性,不同任务对日志的读写操作不会产生冲突。
  4. 资源清理:在任务取消时,要确保所有相关资源(如文件句柄、网络连接等)都能正确释放。