关闭 QT GUI 后如何停止线程
Posted
技术标签:
【中文标题】关闭 QT GUI 后如何停止线程【英文标题】:How to stop a thread after we close the QT GUI 【发布时间】:2019-11-26 05:44:35 【问题描述】:我正在 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();
;
/////////////////////////////////////// ///////////////////////////////////////// /////////////////////////////////////////
【问题讨论】:
【参考方案1】:说停止线程是指在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();
【讨论】:
以上是关于关闭 QT GUI 后如何停止线程的主要内容,如果未能解决你的问题,请参考以下文章
调用 exit() quit() 或 terminate() 后 Qt 线程执行不会停止