docs: rebuild Threading API content
This commit is contained in:
@@ -1,45 +1,57 @@
|
||||
# TaskSystem::Submit
|
||||
|
||||
公开方法,详见头文件声明。
|
||||
|
||||
该方法在 `XCEngine/Threading/TaskSystem.h` 中提供了 2 个重载,当前页面统一汇总这些公开声明。
|
||||
|
||||
## 重载 1: 声明
|
||||
提交一个任务对象或 lambda 到任务系统。
|
||||
|
||||
```cpp
|
||||
uint64_t Submit(std::unique_ptr<ITask> task);
|
||||
```
|
||||
|
||||
**参数:**
|
||||
- `task` - 参数语义详见头文件声明。
|
||||
|
||||
**返回:** `uint64_t` - 返回值语义详见头文件声明。
|
||||
|
||||
## 重载 2: 声明
|
||||
|
||||
```cpp
|
||||
uint64_t Submit(std::function<void()>&& func, TaskPriority priority = TaskPriority::Normal);
|
||||
```
|
||||
|
||||
**参数:**
|
||||
- `func` - 参数语义详见头文件声明。
|
||||
- `priority` - 参数语义详见头文件声明。
|
||||
## 行为说明
|
||||
|
||||
**返回:** `uint64_t` - 返回值语义详见头文件声明。
|
||||
`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。
|
||||
|
||||
```cpp
|
||||
#include <XCEngine/Threading/TaskSystem.h>
|
||||
`Submit(std::function<void()>&&, TaskPriority)` 会先 `new LambdaTask<std::function<void()>>`,再把它包装成 `std::unique_ptr<ITask>` 转发给另一个重载。
|
||||
|
||||
void Example() {
|
||||
XCEngine::Threading::TaskSystem object;
|
||||
// 根据上下文补齐参数后调用 TaskSystem::Submit(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
## 参数
|
||||
|
||||
- `task` - 要提交的任务对象。
|
||||
- `func` - 要包装成任务的可调用对象。
|
||||
- `priority` - lambda 任务优先级。
|
||||
|
||||
## 返回值
|
||||
|
||||
- 成功路径返回新分配的任务 ID。
|
||||
- 当 `task == nullptr` 时返回 `0`。
|
||||
|
||||
## 当前实现风险
|
||||
|
||||
- 当前函数把 `task.get()` 压入队列后,没有 `release()` 也没有额外 `AddRef()`。
|
||||
- 因此 `unique_ptr` 会在函数返回时销毁任务对象,但队列里仍保留裸指针。
|
||||
- 工作线程稍后执行 [ExecuteTask](TaskSystem.md) 路径时,面对的是悬空指针,随后还会调用 `Release()`,这是严重的未定义行为。
|
||||
- 当前提交时不会把任务状态改成 `TaskStatus::Scheduled`。
|
||||
- 当前不会检查系统是否已经 [Shutdown](Shutdown.md)。
|
||||
|
||||
## 设计说明
|
||||
|
||||
商用级任务系统最关键的不是“能把指针塞进队列”,而是任务生命周期必须绝对正确。常见做法一般是:
|
||||
|
||||
- 队列直接持有智能指针。
|
||||
- 或者统一使用 intrusive ref-count,并在入队、出队、执行、完成的每个阶段严格平衡引用。
|
||||
|
||||
当前实现的问题就在于这条最基本的生命周期链路还没有闭合。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](TaskSystem.md)
|
||||
- [返回模块目录](../Threading.md)
|
||||
- [返回类型总览](TaskSystem.md)
|
||||
- [ITask](../Task/Task.md)
|
||||
- [LambdaTask](../LambdaTask/LambdaTask.md)
|
||||
- [Wait](Wait.md)
|
||||
|
||||
Reference in New Issue
Block a user