# thread-interface **Repository Path**: birdman1992/thread-interface ## Basic Information - **Project Name**: thread-interface - **Description**: No description available - **Primary Language**: C++ - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-11-12 - **Last Updated**: 2025-11-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: 跨线程接口调用 ## README # Qt/C++ 跨线程接口架构实现 这是一个基于 Qt/C++ 的跨线程接口架构实现,允许在子线程调用接口方法,而实际执行保持在主线程。 ## 📚 文档资源 - **[项目 Wiki](.qoder/repowiki/zh/content/项目概述.md)** - 完整的架构设计文档、API 参考和使用指南 - **[快速开始](QUICKSTART.md)** - 快速上手指南 - **[实现总结](IMPLEMENTATION_SUMMARY.md)** - 技术实现细节 ## 项目结构 ``` . ├── include/ # 头文件 │ ├── i_plots_engine_server.h # 纯虚接口定义 │ ├── plots_engine_server.h # 实现类头文件 │ ├── plots_engine_server_proxy.h # 代理类头文件 │ ├── plots_engine_server_dispatcher.h # 调度器头文件 │ └── thread_proxy_helper.h # 线程代理辅助工具 ├── src/ # 源文件 │ ├── plots_engine_server.cc │ ├── plots_engine_server_proxy.cc │ └── plots_engine_server_dispatcher.cc ├── examples/ # 示例代码 │ ├── basic_usage.cc # 基础使用示例 │ ├── worker_thread_example.cc # 工作线程示例 │ └── async_sync_comparison.cc # 异步/同步对比示例 ├── tests/ # 单元测试 │ ├── test_plots_engine_server.cc │ ├── test_proxy_sync_calls.cc │ ├── test_proxy_async_calls.cc │ └── test_cross_thread.cc └── CMakeLists.txt # CMake 构建配置 ``` ## 架构特性 ### 核心组件 1. **IPlotsEngineServer** - 纯虚接口层 - 定义了 20+ 个接口方法 - 支持多种参数类型和返回值类型 2. **PlotsEngineServer** - 实现类层 - 继承 QObject 和 IPlotsEngineServer - 运行在主线程,包含实际业务逻辑 - 线程安全由架构保证,无需手动加锁 3. **PlotsEngineServerProxy** - 代理类层 - 继承 IPlotsEngineServer,支持多态使用 - 提供三层 API:override/Async/Sync - 自动处理线程切换 - 主线程调用时自动优化(直接调用) 4. **ThreadProxyHelper** - 辅助工具 - 模板化的同步/异步调用封装 - 基于 Qt 元对象系统 ### 调用模式 代理类提供三层 API,支持不同的使用场景: #### 1. 多态调用(通过接口) 接口 override 方法,支持多态使用,内部调用同步版本: ```cpp // 通过接口指针调用(同步阻塞) IPlotsEngineServer* interface = proxy; bool result = interface->Initialize(config); int plot_id = interface->AddPlot("Plot", data); ``` #### 2. 异步调用(Async 后缀) - void 方法:立即返回,操作在后台执行 - 非 void 方法:返回 QFuture,可异步获取结果 ```cpp // Void 方法异步调用 proxy->ShutdownAsync(); // 立即返回 // 带返回值的异步调用 QFuture future = proxy->AddPlotAsync("Plot", data); int result = future.result(); // 等待结果 ``` #### 3. 同步调用(Sync 后缀) - 阻塞调用线程直到主线程执行完成 - 立即返回结果 ```cpp // 同步调用,等待执行完成 int plot_id = proxy->AddPlotSync("Plot", data); int count = proxy->GetPlotCountSync(); ``` ## 编译构建 ### 依赖要求 - Qt 5.12+ 或 Qt 6.x - CMake 3.16+ - C++17 编译器 ### 构建步骤 ```bash mkdir build && cd build cmake .. cmake --build . ``` ### 运行示例 ```bash # 基础使用示例 ./examples/example_basic # 工作线程示例 ./examples/example_worker_thread # 异步同步对比 ./examples/example_async_sync ``` ### 运行测试 ```bash ctest --verbose ``` ## 使用指南 ### 基本使用 ```cpp #include #include "plots_engine_server.h" #include "plots_engine_server_proxy.h" int main(int argc, char* argv[]) { QCoreApplication app(argc, argv); // 1. 在主线程创建实现类 auto* server = new PlotsEngineServer(&app); // 2. 创建代理(可在任意线程使用) auto* proxy = new PlotsEngineServerProxy(server, &app); // 3. 初始化 QVariantMap config; proxy->InitializeSync(config); // 4. 调用接口方法(同步) int plot_id = proxy->AddPlotSync("MyPlot", {1.0, 2.0, 3.0}); // 5. 调用接口方法(异步) QFuture future = proxy->GetPlotCountAsync(); int count = future.result(); // 6. 多态使用(通过接口指针) IPlotsEngineServer* interface = proxy; bool result = interface->Initialize(config); // override版本 return 0; } ``` ### 在工作线程中使用 ```cpp class WorkerThread : public QThread { protected: void run() override { // 在工作线程中调用代理 int plot_id = proxy_->AddPlotSync("Worker Plot", data); // 或异步调用 QFuture future = proxy_->AddPlotAsync("Async Plot", data); int result = future.result(); } private: PlotsEngineServerProxy* proxy_; }; ``` ## 设计原则 ### Google C++ 编码规范 - 类名使用大驼峰:`PlotsEngineServer` - 函数名使用大驼峰:`AddPlot()` - 成员变量小写加下划线后缀:`plot_count_` - 常量使用 k 前缀:`kMaxRetryCount` - 每行不超过 80 字符 - 使用两个空格缩进 ### 线程安全保证 1. 实现类只在主线程运行,无需加锁 2. 代理层使用 QPointer 防止悬空指针 3. 参数通过值传递或 Qt 隐式共享容器 4. 主线程检测优化避免不必要的线程切换 ### 性能优化 - 主线程调用时直接执行,无线程切换开销 - 使用 Qt 隐式共享容器减少拷贝 - 异步调用避免阻塞调用线程 - 支持批量操作减少跨线程调用次数 ## 扩展新接口 ### 添加步骤 添加新接口需要修改 4 个核心文件,遵循三层 API 模式: 1. **接口层**:在 `i_plots_engine_server.h` 添加纯虚函数 2. **实现层**:在 `plots_engine_server.h/cc` 实现该方法 3. **代理层**:在 `plots_engine_server_proxy.h/cc` 添加三个版本的代理方法 4. **验证**:编译运行测试 ### 完整示例:添加 SaveConfiguration 方法 #### 步骤 1:在接口层添加纯虚函数 ```cpp // include/i_plots_engine_server.h class IPlotsEngineServer { public: // ... 现有方法 ... // 保存配置到文件 // @param file_path: 配置文件路径 // @param config: 配置数据 // @return true if save successful virtual bool SaveConfiguration(const QString& file_path, const QVariantMap& config) = 0; }; ``` #### 步骤 2:在实现类中实现该方法 **头文件** (`include/plots_engine_server.h`): ```cpp class PlotsEngineServer : public QObject, public IPlotsEngineServer { Q_OBJECT public: // ... 现有方法 ... bool SaveConfiguration(const QString& file_path, const QVariantMap& config) override; }; ``` **实现文件** (`src/plots_engine_server.cc`): ```cpp bool PlotsEngineServer::SaveConfiguration( const QString& file_path, const QVariantMap& config) { Q_ASSERT(IsMainThread()); // 确保在主线程执行 qDebug() << "Saving configuration to:" << file_path; // 实现业务逻辑 // ... return true; } ``` #### 步骤 3:在代理类中添加三个版本的方法 **头文件** (`include/plots_engine_server_proxy.h`): ```cpp class PlotsEngineServerProxy : public QObject, public IPlotsEngineServer { Q_OBJECT public: // 版本1: 接口实现(override)- 同步阻塞,支持多态使用 bool SaveConfiguration(const QString& file_path, const QVariantMap& config) override; // 版本2: 异步版本 - 返回 QFuture,不阻塞调用线程 QFuture SaveConfigurationAsync(const QString& file_path, const QVariantMap& config); // 版本3: 显式同步版本 - 阻塞等待结果 bool SaveConfigurationSync(const QString& file_path, const QVariantMap& config); }; ``` **实现文件** (`src/plots_engine_server_proxy.cc`): ```cpp // 版本1: override实现,内部调用Sync版本 bool PlotsEngineServerProxy::SaveConfiguration( const QString& file_path, const QVariantMap& config) { return SaveConfigurationSync(file_path, config); } // 版本2: 异步实现 QFuture PlotsEngineServerProxy::SaveConfigurationAsync( const QString& file_path, const QVariantMap& config) { return AsyncInvoker::Invoke( impl_, &PlotsEngineServer::SaveConfiguration, file_path, config); } // 版本3: 同步实现 bool PlotsEngineServerProxy::SaveConfigurationSync( const QString& file_path, const QVariantMap& config) { return SyncInvoker::Invoke( impl_, &PlotsEngineServer::SaveConfiguration, file_path, config); } ``` #### 步骤 4:编译和使用 ```bash cd build cmake --build . --config Release ``` **使用示例**: ```cpp // 多态使用(通过接口指针) IPlotsEngineServer* interface = proxy; bool result = interface->SaveConfiguration("/path/to/config.json", config); // 异步调用 QFuture future = proxy->SaveConfigurationAsync("/path/to/config.json", config); // ... 做其他事情 ... bool result = future.result(); // 等待结果 // 同步调用 bool result = proxy->SaveConfigurationSync("/path/to/config.json", config); ``` ### 设计要点 **返回类型选择**: - `void` - 不需要返回值的操作 - `int`/`bool` - 简单返回值 - `QVariantMap` - 复杂数据返回 - `QFuture` - 仅用于 Async 版本 **参数传递规范**: - `const 引用` - 大对象(QString, QVector, QVariantMap) - `值传递` - 简单类型(int, bool) - `引用参数` - 输出参数(仅限同步方法) **三层API说明**: 1. **override 版本** - 支持多态,内部调用 Sync 版本 2. **Async 版本** - 异步调用,返回 QFuture,不阻塞 3. **Sync 版本** - 同步调用,阻塞等待结果 ## 许可证 Copyright 2025. All Rights Reserved.