You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 23:49:55