有一个包含std::thread的对象,我希望在销毁该对象时完成该对象。
最小工作代码:
#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;
};它很快变得复杂起来:您只能在loop进入exec()之后调用exit(),您不能在线程外部创建loop。
我只有一个解决方案,其中的信号量是由在此循环中排队等待执行的处理程序释放的。当信号量被释放时,我可以确保循环已经创建并正在运行,因此可以在需要时使用quit()消息终止它。
我是不是错过了一种更简单的方式?
发布于 2017-11-22 19:51:56
也许你可以向线程传递一个对QEventLoop的出口的引用,并在销毁时在该指针上调用unique_ptr。如下所示:
#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;
};发布于 2017-11-22 21:28:06
以下是我对此的看法,基于katrasnikj的回答和std::promise docs,以确保在构造函数完成时线程正在运行。
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;
};但您可能会考虑使用QThread,因为它能够运行自己的事件循环。
https://stackoverflow.com/questions/47432720
复制相似问题