英文:
C++ - How to run a class in separate thread and reference functions from same class in main thread
问题
以下是代码部分的翻译:
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){
// 进行操作
}
}
void Run();
};
#define sVibraniumEngine VibraniumEngine::instance()
int main()
{
std::thread vibraniumEngineThread (&VibraniumEngine::Start, sVibraniumEngine);
// 如何在这里调用 `Run` 方法,就好像它是从 `vibraniumEngineThread` 上下文调用的一样?
}
以上是代码部分的翻译,不包含其他内容。
英文:
I have this:
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 ?
}
This creates a new thread of class VibraniumEngine
and main thread continues execution.
Function VibraniumEngine::Start
holds while
loop.
Vibranium engine has other public variables and methods rather than just Start
.
Is there a way to call these methods from the main thread as if they were called from vibraniumEngineThread
, aka in the context of the created thread, not from the main thread?
答案1
得分: 1
不直接支持,您需要设置自己的队列系统,主线程可以将请求推入队列,然后工作线程从队列中取出请求并根据需要执行它们。
例如:
#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> local_requests;
local_requests.swap(m_requests);
lk.unlock();
while (!local_requests.empty()) {
RequestPtr request = std::move(local_requests.front());
local_requests.pop();
request->DoAction();
}
}
}
// 进行其他操作...
}
}
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;
}
英文:
> Is there a way to call these methods from the main thread as if they were called from vibraniumEngineThread
, aka in the context of the created thread, not from the main thread?
Not directly, no. You would have to setup your own queuing system, where the main thread can push requests into the queue, and then the worker thread pulls out requests from the queue and executes them as needed.
For example:
#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;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论