简体   繁体   English

关闭QT GUI后如何停止线程

[英]How to stop a thread after we close the QT GUI

I am building a application in qt where i am also creating a socket Server in a separate thread using boost. 我正在qt中构建一个应用程序,其中我还使用boost在单独的线程中创建了一个套接字服务器。

Now when i close the GUI of the QT application i want the thread to be closed also. 现在,当我关闭QT应用程序的GUI时,我也希望关闭线程。

But currently i am not able to understand how do we signal the thread to close when we close the 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();
    }

};

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////// ///////////////////////////////////////////////////// ////////////////////////////////////////////////////

By saying stop thread you mean call stop method on io_service instance. 停止线程是指在io_service实例上调用stop方法。 Without this, destructor of boost::thread will be invoked on unfinished thread, what leads to UB. 否则,将在未完成的线程上调用boost::thread析构函数,这将导致UB。

All GUI events are processed in exec method. 所有GUI事件均以exec方法处理。 If you close all windows, this method ends. 如果关闭所有窗口,则此方法结束。 main ends as well, and at the end of main scope all local variables are destroyed. main端也是如此,并且在主作用域的末尾,所有局部变量都被销毁。

So you can just make wrapper for lambda, which will be called at the end of main, and there you can call stop method. 因此,您可以只为lambda制作包装器,该包装器将在main的末尾调用,然后可以在其中调用stop方法。 Then dtor of thread will work without any problems. 然后线程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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM