有一个对象包含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;
};
它变得非常复杂:只有在exit()
进入loop
后,您才能在exec()
上致电loop
,您无法在quit()
之外创建for
线程。
我只有一个信号量的解决方案,该信号量由在此循环中排队等待执行的处理程序释放。释放信号量时,我可以确定循环已创建并正在运行,因此可以在需要时使用$ids = explode(',', $userQrLt['ID']);
$names = explode(',', $userQrLt['Name']);
foreach($i=0;$i<count($ids);$i++) {
echo "http://thewebsite.com/cgi-bin/zd_view.cgi?q=".$ids[$i]."&name=$names[$i]<br />";
}
消息终止。
我错过了一种更简单的方法吗?
答案 0 :(得分:0)
也许你可以将对一个QEventLoop的unique_ptr的引用传递给该线程,并在该指针的destroy调用exit上传递。像这样:
#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;
};
答案 1 :(得分:0)
根据katrasnikj的回答和std::promise docs,根据katrasnikj的回答和{{3}}来确定线程在构造函数完成时运行。
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
来代替,因为它能够运行自己的事件循环。