[英]How to stop a thread after we close the QT GUI
我正在qt中构建一个应用程序,其中我还使用boost在单独的线程中创建了一个套接字服务器。
现在,当我关闭QT应用程序的GUI时,我也希望关闭线程。
但是目前我无法理解在关闭GUI时如何发出信号通知线程关闭。
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
cont.SetName("RootItem");
TreeModel* model = new TreeModel("RootElement", &cont);
WavefrontRenderer w(model);
w.show(); // Show the QT ui
boost::asio::io_service io_service;
server server1(io_service, 1980);
boost::thread t(boost::bind(&io_service::run, &io_service));
return a.exec();
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "ConHandler.h"
#include "WavefrontRenderer.h"
class Server
{
private:
tcp::acceptor acceptor_;
void start_accept()
{
// socket
con_handler::pointer connection = con_handler::create(acceptor_.get_io_service());
// asynchronous accept operation and wait for a new connection.
acceptor_.async_accept(connection->socket(),
boost::bind(&Server::handle_accept, this, connection,
boost::asio::placeholders::error));
}
public:
//constructor for accepting connection from client
Server(boost::asio::io_service& io_service ) : acceptor_(io_service, tcp::endpoint(tcp::v4(), 1980))
{
start_accept();
}
void handle_accept(con_handler::pointer connection, const boost::system::error_code& err)
{
if (!err) {
connection->start();
}
start_accept();
}
};
///////////////////////////////////////////////////// ///////////////////////////////////////////////////// ////////////////////////////////////////////////////
说停止线程是指在io_service
实例上调用stop
方法。 否则,将在未完成的线程上调用boost::thread
析构函数,这将导致UB。
所有GUI事件均以exec
方法处理。 如果关闭所有窗口,则此方法结束。 main
端也是如此,并且在主作用域的末尾,所有局部变量都被销毁。
因此,您可以只为lambda制作包装器,该包装器将在main的末尾调用,然后可以在其中调用stop方法。 然后线程dtor将正常工作。
template<class F>
struct Cleaner {
Cleaner(F in) : f(in) {}
~Cleaner() { f(); }
F f;
};
template<class F>
Cleaner<F> makeCleaner(F f) {
return Cleaner<F>(f);
}
int main()
boost::asio::io_service io_service;
server server1(io_service, 1980);
boost::thread t(boost::bind(&io_service::run, &io_service));
auto raii = makeCleaner( [&](){ io_service.stop(); } );
return a.exec();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.