C++:如何在独立线程运行类并在主线程调用其线程上下文方法
实现主线程提交任务到VibraniumEngine线程执行的方案
要让主线程调用的方法在vibraniumEngineThread的上下文执行,核心思路是给VibraniumEngine添加任务队列+同步机制,让线程的死循环不断从队列中取出任务并执行,主线程只需要把要执行的方法封装成任务投递到队列即可。
修改后的VibraniumEngine实现
#include <thread> #include <queue> #include <functional> #include <mutex> #include <condition_variable> #include <atomic> class VibraniumEngine { public: VibraniumEngine(VibraniumEngine const &) = delete; VibraniumEngine(VibraniumEngine &&) = delete; VibraniumEngine& operator= (VibraniumEngine const&) = delete; VibraniumEngine& operator= (VibraniumEngine&&) = delete; static VibraniumEngine* instance() { static VibraniumEngine instance; return &instance; } void Start() { while (!m_stop.load(std::memory_order_acquire)) { std::function<void()> task; { // 加锁等待任务 std::unique_lock<std::mutex> lock(m_taskMutex); m_taskCond.wait(lock, [this](){ return m_stop.load(std::memory_order_acquire) || !m_taskQueue.empty(); }); // 如果是停止信号,退出循环 if (m_stop.load(std::memory_order_acquire) && m_taskQueue.empty()) { break; } // 取出任务 task = std::move(m_taskQueue.front()); m_taskQueue.pop(); } // 执行任务(解锁后执行,避免阻塞主线程投递任务) if (task) { task(); } } } // 投递任务的接口,主线程调用这个方法提交要执行的逻辑 void PostTask(std::function<void()> task) { if (!task || m_stop.load(std::memory_order_acquire)) { return; } { std::lock_guard<std::mutex> lock(m_taskMutex); m_taskQueue.emplace(std::move(task)); } // 唤醒线程执行任务 m_taskCond.notify_one(); } void Run() { // 这里是你要在引擎线程执行的逻辑 // 示例: // std::cout << "Run executed in thread: " << std::this_thread::get_id() << std::endl; } // 优雅停止线程的方法(可选) void Stop() { m_stop.store(true, std::memory_order_release); m_taskCond.notify_one(); } private: VibraniumEngine() = default; ~VibraniumEngine() { Stop(); } std::queue<std::function<void()>> m_taskQueue; std::mutex m_taskMutex; std::condition_variable m_taskCond; std::atomic<bool> m_stop{false}; // 线程安全的停止标志 }; #define sVibraniumEngine VibraniumEngine::instance() int main() { std::thread vibraniumEngineThread (&VibraniumEngine::Start, sVibraniumEngine); // 主线程投递Run任务到引擎线程执行 sVibraniumEngine->PostTask(std::bind(&VibraniumEngine::Run, sVibraniumEngine)); // 也可以投递带参数的任务或lambda表达式 sVibraniumEngine->PostTask([](){ // 这段逻辑同样会在引擎线程中执行 }); // 等待线程结束(实际场景可根据业务逻辑控制停止时机) sVibraniumEngine->Stop(); vibraniumEngineThread.join(); return 0; }
关键原理说明
- 任务队列:用
std::queue<std::function<void()>>存储待执行任务,支持任意可调用对象(成员函数、lambda、普通函数等)。 - 同步机制:
std::mutex保护队列的读写操作,std::condition_variable在主线程投递任务后唤醒引擎线程,避免线程空转浪费资源。 - 停止标志:
std::atomic<bool>实现线程安全的停止信号,让引擎线程可以优雅退出,避免强制终止线程带来的资源泄漏问题。
使用注意事项
- 如果
Run方法需要参数,可以通过std::bind绑定参数,或用lambda表达式捕获参数来封装任务。 - 任务中访问的共享资源需保证线程安全,必要时添加额外的同步措施。
- 可根据需求扩展任务队列功能,比如添加任务优先级、批量投递等。
内容的提问来源于stack exchange,提问作者Venelin
相关产品推荐
相关产品推荐

