【发布时间】:2018-05-06 01:48:00
【问题描述】:
有一个对象包含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上调用exit(),只有在它进入exec()之后,你不能在线程之外创建loop。
我只有一个带有信号量的解决方案,该信号量由在此循环中排队等待执行的处理程序释放。当信号量被释放时,我可以确定循环已创建并正在运行,因此可以在需要时使用quit() 消息终止它。
我错过了更简单的方法吗?
【问题讨论】:
-
你如何处理
loop?您无法访问它,也无法向其发送事件。 -
@nwp,通过在
exec()之前创建一些对象。类似于套接字的东西,传递一个 IP 地址来连接,std::function回调数据。 -
我没有看到您如何通过套接字与事件循环进行通信。看起来有点像您正在重新实现
QThread。它已经带有事件循环和信号/插槽支持。 -
@nwp,我不需要
QThread。问题是关于std::thread。在问题中添加了一个使用示例。 -
我广泛使用
std::thread和QEventLoop。从那句话我可以想象MySocket实际上是QTcpSocket并且有一些未显示的插槽连接。顺便说一句,使用QThread,您完全可以在线程外创建loop,然后只需使用moveToThread。
标签: c++ multithreading qt concurrency