Qt deleteLater在时间改变时导致崩溃

时间:2017-09-14 15:08:55

标签: multithreading qt

我们创建了一个从QTcpServer派生的Qt HTTP服务器。 每个传入的客户端连接都在一个新的线程中处理,如下所示:

    void WebClientThread::run()
    {

        // Configure the web client socket
        m_socket = new QTcpSocket();

       connect(m_socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
       connect(m_socket, SIGNAL (error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)));

      // Create the actual web client = worker
      WebClient client(m_socket, m_configuration, m_pEventConnection, m_pThumbnailStreams, m_server, m_macAddress, 0 );

     // Thread event loop
     exec();

     m_pLog->LOG(L_INFO, "Webclient thread finished");
   }
   //
   // Client disconnect
   //
   void WebClientThread::disconnected()
   {
       m_socket->deleteLater();
       exit(0);
   }

此代码有效,但是当我们的设备的NTP连接启动并且系统时间从01/01/1970纪元更正到当前时间时,我们遇到应用程序崩溃。 运行应用程序时也可以重现崩溃,同时从脚本中更改系统时间。

应用程序运行正常 - 即使系统时间如此动态变化:

void WebClientThread::run()
{

    // Configure the web client socket
    m_socket = new QTcpSocket();

    connect(m_socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
    connect(m_socket, SIGNAL (error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)));

    // Create the actual web client = worker
    WebClient client(m_socket, m_configuration, m_pEventConnection, m_pThumbnailStreams, m_server, m_macAddress, 0 );

    // Make this thread a loop,
    exec();

    delete m_socket;

    m_pLog->LOG(L_INFO, "Webclient thread finished");

}


//=======================================================================
//
// Client disconnect
//
void WebClientThread::disconnected()
{
    exit(0);
}

为什么deleteLater()会在系统时间转移时使应用程序崩溃?

其他信息:

OS =嵌入式Linux 3.0.0。 Qt = 4.8

套接字是我们的Qt Web服务器应用程序和前端服务器= lighttpd之间的连接。当系统时间转移47年并且我们的Web服务器仍处理请求时,lighttpd是否会关闭套接字?

我可以通过向服务器发送请求来重现它,同时并行运行将日期设置为1980年,1990年和2000年的脚本。它每秒更改一次。

1 个答案:

答案 0 :(得分:0)

这种Qt线程错误使用的气味。如果你从QThread方法调用exec(),我建议你不要继承run(),因为如果你这样做,那就太容易做错了。

请参阅示例https://wiki.qt.io/QThreads_general_usage以了解如何为 QThread 设置worker QObject ,但要点是,创建{{的子类1}}并将您的代码放在那里。然后将其实例移动到QObject实例,并连接信号和插槽以使事情发生。

另外,你通常不应该使用线程进行Qt网络,例如QThread。 Qt是基于事件和异步的,只要您只使用信号和插槽并且永远不会阻塞您的插槽方法,就不需要线程,它们只会使事情复杂化而没有任何好处。只有当你有耗时的计算,或者你的程序真的需要利用多个CPU内核来获得足够好的性能时,才会考虑多线程。