[英]How to properly embed QEventLoop in the std::thread?
There is an object that contains std::thread
that I want to be finished when the object is destroyed. 有一个包含
std::thread
的对象,该对象销毁后我要完成。
Minimal working code: 最少的工作代码:
#include <thread>
#include <future>
#include <QEventLoop>
struct Connector
{
Connector(std::string addr, std::function<void(std::string)> cb)
{
std::promise<void> barrier;
auto fut = barrier.get_future();
m_worker = std::thread([addr, cb, &barrier]()
{
QEventLoop loop;
QTimer::singleShot(0, [this, &barrier, &loop]
{
m_quit = [&loop] { QTimer::singleShot(0, &loop, &QEventLoop::quit); };
barrier.set_value();
});
MySocket s(addr, cb);
loop.exec();
});
fut.wait();
}
~Connector()
{
m_quit();
m_worker.join();
}
std::thread worker;
std::function<void()> m_quit;
};
It becomes complex very fast: you can call exit()
on the loop
only after it enters the exec()
, you can't create the loop
outside of the thread. 它变得非常复杂:您只能在进入
exec()
后在loop
上调用exit()
,而不能在线程外部创建loop
。
I only have a solution with a semaphore that is released by a handler that is queued for the execution in this loop. 我只有一个带有信号量的解决方案,该信号量由在此循环中排队等待执行的处理程序释放。 When the semaphore is released I can be sure that the loop is created and running, so it can be terminated with a
quit()
message when needed. 释放信号量后,我可以确定该循环已创建并正在运行,因此可以在需要时使用
quit()
消息终止该循环。
Am I missing a simpler way? 我想念一个更简单的方法吗?
Maybe you could pass a reference to a unique_ptr of QEventLoop to the thread and at destruction call exit on that pointer. 也许您可以将对QEventLoop的unique_ptr的引用传递给线程,并在该指针的销毁调用出口处传递该引用。 Like this:
像这样:
#include <thread>
#include <QEventLoop>
struct Connector
{
Connector()
{
m_worker = std::thread([=]()
{
event_loop = std::make_unique<QEventLoop>();
loop->exec();
});
}
~Connector()
{
event_loop->exit();
m_worker.join();
}
std::unique_ptr<QEventLoop> event_loop;
std::thread worker;
};
Here's my take on it, based on katrasnikj's answer and std::promise docs to ensure that the thread is running by the time the constructor finishes. 这是我的看法,基于katrasnikj的答案和std :: promise文档,以确保在构造函数完成时线程正在运行。
struct Connector
{
Connector()
{
std::promise<void> barrier;
auto fut = barrier.get_future();
worker = std::thread([=](std::promise<void>&& barrier)
{
event_loop = std::make_unique<QEventLoop>();
barrier.set_value();
event_loop->exec();
}, std::move(barrier));
fut.wait();
}
~Connector()
{
QTimer::singleShot(0, event_loop.get(), &QEventLoop::quit);
worker.join();
}
std::unique_ptr<QEventLoop> event_loop;
std::thread worker;
};
But you might want to look into using QThread
instead, since it's capable of running its own event loop. 但是您可能想研究使用
QThread
,因为它能够运行自己的事件循环。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.