Files
XCEngine/docs/api/XCEngine/Threading/TaskSystem/Submit.md

2.0 KiB
Raw Blame History

TaskSystem::Submit

提交一个任务对象或 lambda 到任务系统。

uint64_t Submit(std::unique_ptr<ITask> task);
uint64_t Submit(std::function<void()>&& func, TaskPriority priority = TaskPriority::Normal);

行为说明

Submit(std::unique_ptr<ITask>) 当前会:

  1. task == nullptr,直接返回 0
  2. 递增 m_nextTaskId 生成新 ID。
  3. 调用 task->SetId(taskId)
  4. task.get() 构造 TaskWrapper
  5. m_queueMutex 保护下把 TaskWrapper 压入优先级队列。
  6. 唤醒一个工作线程。
  7. 返回任务 ID。

Submit(std::function<void()>&&, TaskPriority) 会先 new LambdaTask<std::function<void()>>,再把它包装成 std::unique_ptr<ITask> 转发给另一个重载。

参数

  • task - 要提交的任务对象。
  • func - 要包装成任务的可调用对象。
  • priority - lambda 任务优先级。

返回值

  • 成功路径返回新分配的任务 ID。
  • task == nullptr 时返回 0

当前实现风险

  • 当前函数把 task.get() 压入队列后,没有 release() 也没有额外 AddRef()
  • 因此 unique_ptr 会在函数返回时销毁任务对象,但队列里仍保留裸指针。
  • 工作线程稍后执行 ExecuteTask 路径时,面对的是悬空指针,随后还会调用 Release(),这是严重的未定义行为。
  • 当前提交时不会把任务状态改成 TaskStatus::Scheduled
  • 当前不会检查系统是否已经 Shutdown

设计说明

商用级任务系统最关键的不是“能把指针塞进队列”,而是任务生命周期必须绝对正确。常见做法一般是:

  • 队列直接持有智能指针。
  • 或者统一使用 intrusive ref-count并在入队、出队、执行、完成的每个阶段严格平衡引用。

当前实现的问题就在于这条最基本的生命周期链路还没有闭合。

相关文档