C++ -如何在单独的线程中运行一个类,并在主线程中引用同一个类的函数

rvpgvaaj  于 2023-03-05  发布在  其他
关注(0)|答案(1)|浏览(166)

我有这个:

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(true){
            // Do stuff
        }
    }

    void Run();
};

#define sVibraniumEngine VibraniumEngine::instance()

int main()
{
    std::thread vibraniumEngineThread (&VibraniumEngine::Start, sVibraniumEngine);

    //How can I call here method `Run` as if it was called from `vibraniumEngineThread` context ?
}

这将创建类VibraniumEngine的新线程,主线程将继续执行。
函数VibraniumEngine::Start保持while循环。
Vibranium引擎有其他公共变量和方法,而不仅仅是Start
是否有一种方法可以从主线程调用这些方法,就好像它们是从vibraniumEngineThread调用的一样,也就是在创建的线程的上下文中,而不是从主线程调用的?

ztyzrc3y

ztyzrc3y1#

是否有一种方法可以从主线程调用这些方法,就好像它们是从vibraniumEngineThread调用的一样,也就是在创建的线程的上下文中,而不是从主线程调用的?
不直接,不。您必须设置自己的排队系统,其中主线程可以将请求推入队列,然后工作线程从队列中取出请求并根据需要执行它们。
例如:

#include <queue>
#include <mutex>
#include <memory>

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;
    }

    class Request
    {
    public:
        virtual void DoAction() = 0;
    };
    using RequestPtr = std::unique_ptr<Request>;

    void Start()
    {
        while (true){
            {
                std::unique_lock<std::mutex> lk(m_lock);

                if (!m_requests.empty()) {
                    std::queue<RequestPtr> l_requests;
                    l_requests.swap(m_requests);
                    lk.unlock();

                    while (!l_requests.empty()) {
                        RequestPtr request = std::move(l_requests.front());
                        l_requests.pop();
                        request->DoAction();
                    }
                }
            }

            // Do Other Stuff...
        }
    }

    void Run() { ... }

    template<typename T, typename... Args>
    void AddRequest(Args&&... args)
    {
        std::lock_guard<std::mutex> lk(m_lock);
        m_requests.push(std::make_unique<T>(std::forward<Args>(args)...));
    }

private:
    std::queue<RequestPtr> m_requests;
    std::mutex m_lock;
};

#define sVibraniumEngine VibraniumEngine::instance()

class CallVibraniumEngineRun : public VibraniumEngine::Request
{
public:
    void DoAction() override {
        sVibraniumEngine->Run();
    }
};

int main()
{
    std::thread vibraniumEngineThread (&VibraniumEngine::Start, sVibraniumEngine);
    ...
    sVibraniumEngine->AddRequest<CallVibraniumEngineRun>();
    ...
    return 0;
}

相关问题