docs: rebuild Threading API content
This commit is contained in:
@@ -1,30 +1,31 @@
|
||||
# TaskSystem::CreateTaskGroup
|
||||
|
||||
创建新对象或资源。
|
||||
创建一个新的任务组对象。
|
||||
|
||||
```cpp
|
||||
TaskGroup* CreateTaskGroup();
|
||||
```
|
||||
|
||||
该方法声明于 `XCEngine/Threading/TaskSystem.h`,当前页面用于固定 `TaskSystem` 类目录下的方法级 canonical 路径。
|
||||
## 行为说明
|
||||
|
||||
**参数:** 无。
|
||||
当前实现会:
|
||||
|
||||
**返回:** `TaskGroup*` - 返回值语义详见头文件声明。
|
||||
1. 通过 `new TaskGroup()` 分配一个任务组。
|
||||
2. 在 `m_groupMutex` 保护下把该指针加入 `m_taskGroups`。
|
||||
3. 返回这个裸指针。
|
||||
|
||||
**示例:**
|
||||
## 返回值
|
||||
|
||||
```cpp
|
||||
#include <XCEngine/Threading/TaskSystem.h>
|
||||
- 新创建的 `TaskGroup*`。
|
||||
|
||||
void Example() {
|
||||
XCEngine::Threading::TaskSystem object;
|
||||
// 根据上下文补齐参数后调用 TaskSystem::CreateTaskGroup(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
## 当前实现限制
|
||||
|
||||
- 当前只是在系统内部登记这个指针,并没有让任务组自动接入任务调度。
|
||||
- 返回裸指针意味着所有权由调用方显式管理。
|
||||
- 当前 [Shutdown](Shutdown.md) 不会自动销毁这些任务组。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](TaskSystem.md)
|
||||
- [返回模块目录](../Threading.md)
|
||||
- [返回类型总览](TaskSystem.md)
|
||||
- [TaskGroup](../TaskGroup/TaskGroup.md)
|
||||
- [DestroyTaskGroup](DestroyTaskGroup.md)
|
||||
|
||||
@@ -1,31 +1,35 @@
|
||||
# TaskSystem::DestroyTaskGroup
|
||||
|
||||
公开方法,详见头文件声明。
|
||||
销毁一个由任务系统创建的任务组。
|
||||
|
||||
```cpp
|
||||
void DestroyTaskGroup(TaskGroup* group);
|
||||
```
|
||||
|
||||
该方法声明于 `XCEngine/Threading/TaskSystem.h`,当前页面用于固定 `TaskSystem` 类目录下的方法级 canonical 路径。
|
||||
## 行为说明
|
||||
|
||||
**参数:**
|
||||
- `group` - 参数语义详见头文件声明。
|
||||
当前实现会:
|
||||
|
||||
**返回:** `void` - 无返回值。
|
||||
1. 若 `group == nullptr`,直接返回。
|
||||
2. 在 `m_groupMutex` 保护下,从 `m_taskGroups` 中查找并移除该指针。
|
||||
3. 在锁外执行 `delete group`。
|
||||
|
||||
**示例:**
|
||||
## 参数
|
||||
|
||||
```cpp
|
||||
#include <XCEngine/Threading/TaskSystem.h>
|
||||
- `group` - 要销毁的任务组。
|
||||
|
||||
void Example() {
|
||||
XCEngine::Threading::TaskSystem object;
|
||||
// 根据上下文补齐参数后调用 TaskSystem::DestroyTaskGroup(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
## 返回值
|
||||
|
||||
- 无。
|
||||
|
||||
## 当前实现限制
|
||||
|
||||
- 当前不会先 [Cancel](../TaskGroup/Cancel.md) 或 [Wait](../TaskGroup/Wait.md)。
|
||||
- 若任务组内部已有通过 [TaskGroup::AddTask](../TaskGroup/AddTask.md) 存进去的任务对象,`delete group` 也不会释放这些裸任务指针。
|
||||
- 如果传入的指针不在 `m_taskGroups` 列表里,当前实现仍会直接 `delete group`。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](TaskSystem.md)
|
||||
- [返回模块目录](../Threading.md)
|
||||
- [返回类型总览](TaskSystem.md)
|
||||
- [CreateTaskGroup](CreateTaskGroup.md)
|
||||
- [TaskGroup](../TaskGroup/TaskGroup.md)
|
||||
|
||||
@@ -1,29 +1,30 @@
|
||||
# TaskSystem::Get
|
||||
|
||||
获取相关状态或对象。
|
||||
取得全局任务系统单例。
|
||||
|
||||
```cpp
|
||||
static TaskSystem& Get();
|
||||
```
|
||||
|
||||
该方法声明于 `XCEngine/Threading/TaskSystem.h`,当前页面用于固定 `TaskSystem` 类目录下的方法级 canonical 路径。
|
||||
## 行为说明
|
||||
|
||||
**参数:** 无。
|
||||
|
||||
**返回:** `TaskSystem&` - 返回值语义详见头文件声明。
|
||||
|
||||
**示例:**
|
||||
当前实现返回一个函数内静态对象:
|
||||
|
||||
```cpp
|
||||
#include <XCEngine/Threading/TaskSystem.h>
|
||||
|
||||
void Example() {
|
||||
auto& instance = XCEngine::Threading::TaskSystem::Get();
|
||||
(void)instance;
|
||||
}
|
||||
static TaskSystem instance;
|
||||
```
|
||||
|
||||
## 返回值
|
||||
|
||||
- `TaskSystem` 的全局唯一实例引用。
|
||||
|
||||
## 注意事项
|
||||
|
||||
- 取得实例并不会自动调用 [Initialize](Initialize.md)。
|
||||
- 由于构造函数和析构函数是私有的,外部只能通过这个入口访问任务系统。
|
||||
- 当前单例持有线程、队列和任务组列表,因此生命周期等同于整个进程内的静态对象生命周期。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](TaskSystem.md)
|
||||
- [返回模块目录](../Threading.md)
|
||||
- [返回类型总览](TaskSystem.md)
|
||||
- [Initialize](Initialize.md)
|
||||
|
||||
@@ -1,30 +1,25 @@
|
||||
# TaskSystem::GetWorkerThreadCount
|
||||
|
||||
获取相关状态或对象。
|
||||
返回当前记录的工作线程数。
|
||||
|
||||
```cpp
|
||||
uint32_t GetWorkerThreadCount() const;
|
||||
```
|
||||
|
||||
该方法声明于 `XCEngine/Threading/TaskSystem.h`,当前页面用于固定 `TaskSystem` 类目录下的方法级 canonical 路径。
|
||||
## 行为说明
|
||||
|
||||
**参数:** 无。
|
||||
当前实现直接返回成员 `m_workerThreadCount`。
|
||||
|
||||
**返回:** `uint32_t` - 返回值语义详见头文件声明。
|
||||
## 返回值
|
||||
|
||||
**示例:**
|
||||
- 当前配置的工作线程数量。
|
||||
|
||||
```cpp
|
||||
#include <XCEngine/Threading/TaskSystem.h>
|
||||
## 注意事项
|
||||
|
||||
void Example() {
|
||||
XCEngine::Threading::TaskSystem object;
|
||||
// 根据上下文补齐参数后调用 TaskSystem::GetWorkerThreadCount(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
- 在 [Initialize](Initialize.md) 之前,这个值默认是 `0`。
|
||||
- 这个值表示“初始化时决定的目标线程数”,不表示当前仍然活跃的线程数量。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](TaskSystem.md)
|
||||
- [返回模块目录](../Threading.md)
|
||||
- [返回类型总览](TaskSystem.md)
|
||||
- [Initialize](Initialize.md)
|
||||
|
||||
@@ -1,31 +1,39 @@
|
||||
# TaskSystem::Initialize
|
||||
|
||||
初始化内部状态。
|
||||
初始化任务系统并创建工作线程。
|
||||
|
||||
```cpp
|
||||
void Initialize(const TaskSystemConfig& config);
|
||||
```
|
||||
|
||||
该方法声明于 `XCEngine/Threading/TaskSystem.h`,当前页面用于固定 `TaskSystem` 类目录下的方法级 canonical 路径。
|
||||
## 行为说明
|
||||
|
||||
**参数:**
|
||||
- `config` - 参数语义详见头文件声明。
|
||||
当前实现会:
|
||||
|
||||
**返回:** `void` - 无返回值。
|
||||
1. 从 `config.workerThreadCount` 读取目标线程数。
|
||||
2. 当该值为 `0` 时,退回到 `std::thread::hardware_concurrency()`。
|
||||
3. 若仍为 `0`,最终使用 `2`。
|
||||
4. 把 `m_running` 设为 `true`。
|
||||
5. 启动对应数量的 `std::thread`,每个线程执行内部 `WorkerThread()` 循环。
|
||||
|
||||
**示例:**
|
||||
## 参数
|
||||
|
||||
```cpp
|
||||
#include <XCEngine/Threading/TaskSystem.h>
|
||||
- `config` - 任务系统初始化配置。
|
||||
|
||||
void Example() {
|
||||
XCEngine::Threading::TaskSystem object;
|
||||
// 根据上下文补齐参数后调用 TaskSystem::Initialize(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
## 返回值
|
||||
|
||||
- 无。
|
||||
|
||||
## 当前实现限制
|
||||
|
||||
- 当前只真正使用 `workerThreadCount`,其余配置字段都会被忽略。
|
||||
- 当前没有防止重复初始化的保护;多次调用会继续往 `m_workerThreads` 里追加线程。
|
||||
- 当前不会把 `m_shutdown` 重置回 `false`,因此一旦执行过 [Shutdown](Shutdown.md),再次 `Initialize()` 的行为是不完整的。
|
||||
- 当前不会清空历史队列或主线程回调队列。
|
||||
- 当前不会给工作线程命名,也没有线程绑定、栈大小或亲和性设置。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](TaskSystem.md)
|
||||
- [返回模块目录](../Threading.md)
|
||||
- [返回类型总览](TaskSystem.md)
|
||||
- [TaskSystemConfig](../TaskSystemConfig/TaskSystemConfig.md)
|
||||
- [Shutdown](Shutdown.md)
|
||||
|
||||
@@ -1,33 +1,54 @@
|
||||
# TaskSystem::ParallelFor
|
||||
|
||||
公开方法,详见头文件声明。
|
||||
把一个整数区间拆分成多个任务并提交执行。
|
||||
|
||||
```cpp
|
||||
template<typename Func> void ParallelFor(int32_t start, int32_t end, Func&& func);
|
||||
template<typename Func>
|
||||
void ParallelFor(int32_t start, int32_t end, Func&& func);
|
||||
```
|
||||
|
||||
该方法声明于 `XCEngine/Threading/TaskSystem.h`,当前页面用于固定 `TaskSystem` 类目录下的方法级 canonical 路径。
|
||||
## 行为说明
|
||||
|
||||
**参数:**
|
||||
- `start` - 参数语义详见头文件声明。
|
||||
- `end` - 参数语义详见头文件声明。
|
||||
- `func` - 参数语义详见头文件声明。
|
||||
当前模板实现会:
|
||||
|
||||
**返回:** `template<typename Func> void` - 返回值语义详见头文件声明。
|
||||
1. 计算区间长度 `count = end - start`。
|
||||
2. 若 `count <= 0`,直接返回。
|
||||
3. 用 `std::thread::hardware_concurrency()` 决定分片数量;若返回 `0`,回退到 `2`。
|
||||
4. 按 `(count + numThreads - 1) / numThreads` 计算块大小。
|
||||
5. 为每个分片构造一个高优先级 lambda 任务。
|
||||
6. 逐个调用 [Submit](Submit.md) 提交这些任务。
|
||||
|
||||
**示例:**
|
||||
## 参数
|
||||
|
||||
```cpp
|
||||
#include <XCEngine/Threading/TaskSystem.h>
|
||||
- `start` - 起始索引,包含。
|
||||
- `end` - 结束索引,不包含。
|
||||
- `func` - 对区间内每个索引执行的可调用对象。
|
||||
|
||||
void Example() {
|
||||
XCEngine::Threading::TaskSystem object;
|
||||
// 根据上下文补齐参数后调用 TaskSystem::ParallelFor(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
## 返回值
|
||||
|
||||
- 无。
|
||||
|
||||
## 当前实现限制
|
||||
|
||||
- 当前函数提交完任务后立即返回,不会等待所有分片完成。
|
||||
- 当前按硬件并发数分片,而不是按 [Initialize](Initialize.md) 配置的工作线程数分片。
|
||||
- 当前头文件里模板使用了 `LambdaTask` 和 `std::min`,但 `TaskSystem.h` 自身没有包含 `LambdaTask.h` 和 `<algorithm>`;如果只包含这个头,模板实例化可能失败。
|
||||
- 当前底层仍然依赖 [Submit](Submit.md),因此会继承任务生命周期悬空指针问题。
|
||||
- 当 `numThreads > count` 时,会提交一些空分片任务。
|
||||
|
||||
## 设计说明
|
||||
|
||||
商业级 `ParallelFor` 通常至少还需要:
|
||||
|
||||
- 同步栅栏或等待句柄。
|
||||
- 更合理的分块策略。
|
||||
- 工作窃取或局部队列。
|
||||
- 对小任务的过度拆分抑制。
|
||||
|
||||
当前版本更接近“把并行循环 API 形状先搭出来”。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](TaskSystem.md)
|
||||
- [返回模块目录](../Threading.md)
|
||||
- [返回类型总览](TaskSystem.md)
|
||||
- [Submit](Submit.md)
|
||||
- [Synchronization And Task System Limits](../../../_guides/Threading/Synchronization-And-TaskSystem-Limits.md)
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
# TaskSystem::RunOnMainThread
|
||||
|
||||
公开方法,详见头文件声明。
|
||||
把一个回调排入主线程执行队列。
|
||||
|
||||
```cpp
|
||||
void RunOnMainThread(std::function<void()>&& func);
|
||||
```
|
||||
|
||||
该方法声明于 `XCEngine/Threading/TaskSystem.h`,当前页面用于固定 `TaskSystem` 类目录下的方法级 canonical 路径。
|
||||
## 行为说明
|
||||
|
||||
**参数:**
|
||||
- `func` - 参数语义详见头文件声明。
|
||||
当前实现会在 `m_queueMutex` 保护下把回调追加到 `m_mainThreadQueue`。
|
||||
|
||||
**返回:** `void` - 无返回值。
|
||||
这些回调不会立即执行,而是等待 [Update](Update.md) 被调用时再统一消费。
|
||||
|
||||
**示例:**
|
||||
## 参数
|
||||
|
||||
```cpp
|
||||
#include <XCEngine/Threading/TaskSystem.h>
|
||||
- `func` - 需要在主线程执行的回调。
|
||||
|
||||
void Example() {
|
||||
XCEngine::Threading::TaskSystem object;
|
||||
// 根据上下文补齐参数后调用 TaskSystem::RunOnMainThread(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
## 返回值
|
||||
|
||||
- 无。
|
||||
|
||||
## 注意事项
|
||||
|
||||
- 当前实现本身不检查调用线程是否为主线程;“主线程”只是通过谁来调用 [Update](Update.md) 约定出来的。
|
||||
- 当前没有队列容量限制,也没有通知等待主线程的机制。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](TaskSystem.md)
|
||||
- [返回模块目录](../Threading.md)
|
||||
- [返回类型总览](TaskSystem.md)
|
||||
- [Update](Update.md)
|
||||
|
||||
@@ -1,30 +1,45 @@
|
||||
# TaskSystem::Shutdown
|
||||
|
||||
关闭并清理内部状态。
|
||||
关闭任务系统并回收工作线程。
|
||||
|
||||
```cpp
|
||||
void Shutdown();
|
||||
```
|
||||
|
||||
该方法声明于 `XCEngine/Threading/TaskSystem.h`,当前页面用于固定 `TaskSystem` 类目录下的方法级 canonical 路径。
|
||||
## 行为说明
|
||||
|
||||
**参数:** 无。
|
||||
当前实现会:
|
||||
|
||||
**返回:** `void` - 无返回值。
|
||||
1. 把 `m_running` 设为 `false`。
|
||||
2. 把 `m_shutdown` 设为 `true`。
|
||||
3. `notify_all()` 唤醒等待任务的工作线程。
|
||||
4. 逐个 `join()` 仍然可连接的工作线程。
|
||||
5. 清空 `m_workerThreads`。
|
||||
|
||||
**示例:**
|
||||
## 返回值
|
||||
|
||||
```cpp
|
||||
#include <XCEngine/Threading/TaskSystem.h>
|
||||
- 无。
|
||||
|
||||
void Example() {
|
||||
XCEngine::Threading::TaskSystem object;
|
||||
// 根据上下文补齐参数后调用 TaskSystem::Shutdown(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
## 当前实现限制
|
||||
|
||||
- 当前不会清空 `m_taskQueue`,未执行的任务会被直接遗留。
|
||||
- 当前不会释放队列中残留任务对应的对象。
|
||||
- 当前不会销毁已经通过 [CreateTaskGroup](CreateTaskGroup.md) 创建的任务组。
|
||||
- 当前不会清空 `m_mainThreadQueue`。
|
||||
- `m_shutdown` 会一直保持为 `true`,这使得重新初始化路径当前不可用。
|
||||
|
||||
## 设计说明
|
||||
|
||||
商业级任务系统的关闭通常需要定义明确的 shutdown policy,例如:
|
||||
|
||||
- 等待现有任务自然跑完。
|
||||
- 取消可取消任务并清理资源。
|
||||
- 强制丢弃队列但保证对象生命周期可回收。
|
||||
|
||||
当前实现只覆盖了“停线程”这一步。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](TaskSystem.md)
|
||||
- [返回模块目录](../Threading.md)
|
||||
- [返回类型总览](TaskSystem.md)
|
||||
- [Initialize](Initialize.md)
|
||||
- [Submit](Submit.md)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -6,35 +6,72 @@
|
||||
|
||||
**头文件**: `XCEngine/Threading/TaskSystem.h`
|
||||
|
||||
**描述**: 定义 `XCEngine/Threading` 子目录中的 `TaskSystem` public API。
|
||||
**描述**: 提供全局任务调度入口、工作线程池、主线程回调队列以及任务组创建接口。
|
||||
|
||||
## 概述
|
||||
|
||||
`TaskSystem.h` 是 `XCEngine/Threading` 子目录 下的 public header,当前页面作为平行目录中的 canonical 总览,用于汇总该头文件暴露的主要声明。
|
||||
`TaskSystem` 想解决的是“把零散后台工作统一交给一套中央调度器管理”这个问题。它当前暴露的 API 形状已经覆盖了商用引擎任务系统常见的几个入口:
|
||||
|
||||
## 声明概览
|
||||
- 单例式全局访问。
|
||||
- 工作线程池初始化与关闭。
|
||||
- 按优先级提交任务。
|
||||
- 批量任务入口 `ParallelFor()`。
|
||||
- 任务组创建与销毁。
|
||||
- 回投主线程的回调队列。
|
||||
|
||||
| 声明 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `TaskSystem` | `class` | 头文件中的公开声明。 |
|
||||
这种设计方向本身是对的。商业级引擎很少要求上层系统自己手搓 `std::thread`,而是倾向于通过中央 job system 统一调度、限流、统计和同步。
|
||||
|
||||
## 公共方法
|
||||
## 当前实现边界
|
||||
|
||||
| 方法 | 描述 |
|
||||
当前 `TaskSystem` 仍然明显处于原型阶段,尤其要注意以下事实:
|
||||
|
||||
- [Submit](Submit.md) 当前存在严重生命周期问题: 任务指针被压入队列后,对应 `unique_ptr` 却会在函数返回时销毁对象,导致队列中留下悬空指针。
|
||||
- 工作线程取任务时,`GetNextTask()` 访问 `m_taskQueue` 没有使用与入队一致的 `m_queueMutex`,当前存在未同步并发访问。
|
||||
- [Wait](Wait.md) 还是空实现。
|
||||
- [ParallelFor](ParallelFor.md) 会立即返回,不会等待所有分片完成。
|
||||
- [Initialize](Initialize.md) 只真正使用了 `TaskSystemConfig::workerThreadCount`,其余配置项当前都被忽略。
|
||||
- [Shutdown](Shutdown.md) 之后 `m_shutdown` 不会恢复为 `false`,重新初始化路径当前基本不可用。
|
||||
- [TaskGroup](../TaskGroup/TaskGroup.md) 创建出来后,只是被登记到列表里,并没有接入任务执行与完成统计。
|
||||
|
||||
因此,当前 `TaskSystem` 不应被当成商业级 job system 使用。更准确的定位是: API 轮廓已经出现,但核心正确性还没有收敛。
|
||||
|
||||
## 公开方法
|
||||
|
||||
| 方法 | 说明 |
|
||||
|------|------|
|
||||
| [Get](Get.md) | 获取相关状态或对象。 |
|
||||
| [Initialize](Initialize.md) | 初始化内部状态。 |
|
||||
| [Shutdown](Shutdown.md) | 关闭并清理内部状态。 |
|
||||
| [Submit](Submit.md) | 公开方法,详见头文件声明。 |
|
||||
| [CreateTaskGroup](CreateTaskGroup.md) | 创建新对象或资源。 |
|
||||
| [DestroyTaskGroup](DestroyTaskGroup.md) | 公开方法,详见头文件声明。 |
|
||||
| [Wait](Wait.md) | 公开方法,详见头文件声明。 |
|
||||
| [GetWorkerThreadCount](GetWorkerThreadCount.md) | 获取相关状态或对象。 |
|
||||
| [Update](Update.md) | 更新运行时状态。 |
|
||||
| [ParallelFor](ParallelFor.md) | 公开方法,详见头文件声明。 |
|
||||
| [RunOnMainThread](RunOnMainThread.md) | 公开方法,详见头文件声明。 |
|
||||
| [Get](Get.md) | 取得全局单例实例。 |
|
||||
| [Initialize](Initialize.md) | 初始化工作线程池。 |
|
||||
| [Shutdown](Shutdown.md) | 停止工作线程并关闭系统。 |
|
||||
| [Submit](Submit.md) | 提交一个任务对象或 lambda。 |
|
||||
| [CreateTaskGroup](CreateTaskGroup.md) | 创建任务组。 |
|
||||
| [DestroyTaskGroup](DestroyTaskGroup.md) | 销毁任务组。 |
|
||||
| [Wait](Wait.md) | 等待指定任务完成。 |
|
||||
| [GetWorkerThreadCount](GetWorkerThreadCount.md) | 查询当前配置的工作线程数。 |
|
||||
| [Update](Update.md) | 执行主线程回调队列。 |
|
||||
| [ParallelFor](ParallelFor.md) | 把区间拆成多个高优先级任务提交。 |
|
||||
| [RunOnMainThread](RunOnMainThread.md) | 把回调排入主线程队列。 |
|
||||
|
||||
## 设计说明
|
||||
|
||||
为什么引擎仍然需要这样的中心化系统,而不是到处直接开线程:
|
||||
|
||||
- 线程数量需要统一治理,否则很容易过量创建后台线程。
|
||||
- 优先级、主线程回投、profiling 和依赖图等能力,通常都需要一个公共调度中心。
|
||||
- 资源加载、脚本预处理、导航构建、烘焙和编辑器后台任务,往往都需要共享同一套任务基础设施。
|
||||
|
||||
这也是为什么很多商业引擎会把“线程原语”和“任务系统”都保留下来:
|
||||
|
||||
- 锁和线程解决底层同步与平台适配问题。
|
||||
- 任务系统解决更高层的批处理、吞吐量和生命周期协调问题。
|
||||
|
||||
## 使用建议
|
||||
|
||||
- 当前源码中,低层同步原语比 `TaskSystem` 更成熟。
|
||||
- 如果确实要继续推进这个模块,优先修正任务所有权、队列同步、等待语义和关闭语义,再谈 profiling、work stealing 或任务依赖图。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [当前目录](../Threading.md) - 返回 `Threading` 平行目录
|
||||
- [API 总索引](../../../main.md) - 返回顶层索引
|
||||
- [当前模块](../Threading.md)
|
||||
- [TaskSystemConfig](../TaskSystemConfig/TaskSystemConfig.md)
|
||||
- [TaskGroup](../TaskGroup/TaskGroup.md)
|
||||
- [Synchronization And Task System Limits](../../../_guides/Threading/Synchronization-And-TaskSystem-Limits.md)
|
||||
|
||||
@@ -1,30 +1,34 @@
|
||||
# TaskSystem::Update
|
||||
|
||||
更新运行时状态。
|
||||
执行当前积压的主线程回调。
|
||||
|
||||
```cpp
|
||||
void Update();
|
||||
```
|
||||
|
||||
该方法声明于 `XCEngine/Threading/TaskSystem.h`,当前页面用于固定 `TaskSystem` 类目录下的方法级 canonical 路径。
|
||||
## 行为说明
|
||||
|
||||
**参数:** 无。
|
||||
当前实现会:
|
||||
|
||||
**返回:** `void` - 无返回值。
|
||||
1. 在 `m_queueMutex` 保护下把 `m_mainThreadQueue` 整体移动到局部数组。
|
||||
2. 清空内部队列。
|
||||
3. 在锁外按顺序执行这些回调。
|
||||
|
||||
**示例:**
|
||||
## 返回值
|
||||
|
||||
```cpp
|
||||
#include <XCEngine/Threading/TaskSystem.h>
|
||||
- 无。
|
||||
|
||||
void Example() {
|
||||
XCEngine::Threading::TaskSystem object;
|
||||
// 根据上下文补齐参数后调用 TaskSystem::Update(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
## 设计说明
|
||||
|
||||
这是一种典型的“后台线程投递,主线程集中消费”模型。商业引擎里资源系统、脚本系统和编辑器工具都经常需要这种回投路径,因为很多对象只能在主线程安全访问。
|
||||
|
||||
## 当前实现限制
|
||||
|
||||
- 当前不会自动调用,需要调用方在主线程帧循环里显式执行。
|
||||
- `m_mainThreadCondition` 当前没有被使用。
|
||||
- 当前没有异常隔离;某个回调抛出异常时,会中断后续回调执行路径。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](TaskSystem.md)
|
||||
- [返回模块目录](../Threading.md)
|
||||
- [返回类型总览](TaskSystem.md)
|
||||
- [RunOnMainThread](RunOnMainThread.md)
|
||||
|
||||
@@ -1,31 +1,36 @@
|
||||
# TaskSystem::Wait
|
||||
|
||||
公开方法,详见头文件声明。
|
||||
等待指定任务完成。
|
||||
|
||||
```cpp
|
||||
void Wait(uint64_t taskId);
|
||||
```
|
||||
|
||||
该方法声明于 `XCEngine/Threading/TaskSystem.h`,当前页面用于固定 `TaskSystem` 类目录下的方法级 canonical 路径。
|
||||
## 行为说明
|
||||
|
||||
**参数:**
|
||||
- `taskId` - 参数语义详见头文件声明。
|
||||
当前实现是一个空函数体,参数 `taskId` 也没有被使用。
|
||||
|
||||
**返回:** `void` - 无返回值。
|
||||
## 参数
|
||||
|
||||
**示例:**
|
||||
- `taskId` - 目标任务 ID。
|
||||
|
||||
```cpp
|
||||
#include <XCEngine/Threading/TaskSystem.h>
|
||||
## 返回值
|
||||
|
||||
void Example() {
|
||||
XCEngine::Threading::TaskSystem object;
|
||||
// 根据上下文补齐参数后调用 TaskSystem::Wait(...)。
|
||||
(void)object;
|
||||
}
|
||||
```
|
||||
- 无。
|
||||
|
||||
## 当前实现限制
|
||||
|
||||
- 当前不会阻塞。
|
||||
- 当前不会轮询任务状态。
|
||||
- 当前不会配合条件变量、future 或任务组做任何同步。
|
||||
|
||||
## 使用建议
|
||||
|
||||
- 当前不要依赖这个接口实现任务完成等待。
|
||||
- 如果后续要把它补成可用接口,至少需要有一个以任务 ID 为键的完成状态表或句柄系统。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [返回类总览](TaskSystem.md)
|
||||
- [返回模块目录](../Threading.md)
|
||||
- [返回类型总览](TaskSystem.md)
|
||||
- [Submit](Submit.md)
|
||||
- [TaskGroup::Wait](../TaskGroup/Wait.md)
|
||||
|
||||
Reference in New Issue
Block a user