2.0 KiB
2.0 KiB
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>) 当前会:
- 若
task == nullptr,直接返回0。 - 递增
m_nextTaskId生成新 ID。 - 调用
task->SetId(taskId)。 - 用
task.get()构造TaskWrapper。 - 在
m_queueMutex保护下把TaskWrapper压入优先级队列。 - 唤醒一个工作线程。
- 返回任务 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,并在入队、出队、执行、完成的每个阶段严格平衡引用。
当前实现的问题就在于这条最基本的生命周期链路还没有闭合。