Qt线程,从QObject的析构函数崩溃移动

时间:2013-10-09 11:47:52

标签: c++ multithreading qt4 qthread

我正在尝试将连接处理程序(包含QTCPSocket对象)移动到QMainWindow对象的单独线程中。

到目前为止它有效,但是如果我关闭了QMainWindow,它会崩溃并且我会收到以下信息:

  

在QCoreApplication :: sendEvent中失败:“无法将事件发送到不同线程拥有的对象。当前线程1680d0。接收器''(类型为'QAbstractSocket')是在线程34fe0c中创建的”

这是我的代码: 在QMainWindow构造函数中(子类):

QThread m_commsThread;
m_pICommsHandler = new CommsHandlerIP();
m_pICommsHandler->moveToThread(&m_commsThread);
// when it starts, we start the connection
connect(&m_commsThread,SIGNAL(started()),m_pICommsHandler,SLOT(connectToHost()));
m_commsThread.start();

在QMainWindow析构函数中:

m_commsThread.quit();
m_commsThread.wait();
delete m_pICommsHandler;

关于CommsHandlerIP.cpp

CommsHandlerIP::CommsHandlerIP() {
m_TCPSocket = new QTcpSocket(this);
}

CommsHandlerIP::~CommsHandlerIP(void)
{
m_TCPSocket->deleteLater(); // It's going to crash a bit later if I have this line
}

m_TCPSocket应该在正确的线程中被删除,但我觉得通过关闭主线程,亲和力变得凌乱。

我该怎么办?

1 个答案:

答案 0 :(得分:0)

我认为可能会发生两件事:

  1. 据我记忆,在moveToThread()上拨打QAbstractSocket时,Qt4总会遇到一些问题。
  2. 当您在套接字上调用deleteLater()时,它所在的线程已经停止。
  3. 可能的解决方案可能是从CommsHandlerIP继承您的QThread并覆盖run()

    CommsHandlerIP::CommsHandlerIP() :
        QThread(),
        m_TCPSocket(0)
    {
        moveToThread(this);
    }
    
    void CommsHandlerIP::run()
    {
        m_TCPSocket = new QTcpSocket(this);
        connectToHost();
    
        exec();
    
        m_TCPSocket->close();
        delete m_TCPSocket;
    }