如何在调用 movetothread() 后停止 Qthread?
How to stop a Qthread after calling movetothread()?
当我重新实现 QTcpserver::incomingConnection() 时,一个新的 QThread 和一个新的 QTcpsocket 是 created.The accept-fd 被传递给 QTcpsocket。但是,整个过程意外退出时会出现警告:
QThread:线程仍在时被销毁运行
因为 Qthread 调用 quit() 并且这两个对象将被删除。这是下面的代码。
void TcpServer::incomingConnection(qintptr handle)
{
QThread* tcpThread = new QThread;
TcpSocket* tcpSocket = new TcpSocket;
tcpSocket->setSocketDescriptor(handle);
tcpSocket->moveToThread(tcpThread);
connect(tcpSocket,&TcpSocket::sigRecvFinish, [=](){
tcpThread->quit();
delete tcpSocket;
delete tcpThread;
});
tcpThread->start();
}
如何正确退出线程释放资源?同时,是什么导致了这个问题?
如果你能帮我解决这个问题,我将不胜感激。
您需要用以下代码替换您的 connect
:
connect( tcpSocket, &TcpSocket::sigRecvFinish, tcpSocket, &QObject::deleteLater );
connect( tcpSocket, &QObject::destroyed, tcpThread, &QThread::quit );
connect( tcpThread, &QThread::finished, tcpThread, &QThread::deleteLater );
首先 Qt 有很好的异步功能 API 所以线程的使用(在这种情况下)已经完全过时并且浪费资源。
通过在 connect 语句中使用 lambda,您失去了线程跳跃功能,这是默认由 connect
完成的。结果是您试图从该对象管理的线程中销毁线程对象。
请注意 QObject::connect last argument is: Qt::ConnectionType type = Qt::AutoConnection
(connections without lambda). When lambda is used QObject::connect 没有这样的功能,代码是从调用信号的线程调用的。
删除 lambda 将确保每次调用都在正确的线程上完成。
void TcpServer::incomingConnection(qintptr handle)
{
QThread* tcpThread = new QThread;
TcpSocket* tcpSocket = new TcpSocket;
tcpSocket->setSocketDescriptor(handle);
tcpSocket->moveToThread(tcpThread);
connect(tcpSocket, &TcpSocket::sigRecvFinish, tcpSocket, &QBject::delteLater);
connect(tcpSocket, &TcpSocket::sigRecvFinish, tcpThread, &QThread::quit);
connect( tcpThread, &QThread::finished, tcpThread, &QThread::deleteLater );
tcpThread->start();
}
有关技术细节,请参阅:
Constant
Value
Description
Qt::AutoConnection
0
(Default) If the receiver lives in the thread that emits the signal, Qt::DirectConnection is used. Otherwise, Qt::QueuedConnection is used. The connection type is determined when the signal is emitted.
当我重新实现 QTcpserver::incomingConnection() 时,一个新的 QThread 和一个新的 QTcpsocket 是 created.The accept-fd 被传递给 QTcpsocket。但是,整个过程意外退出时会出现警告: QThread:线程仍在时被销毁运行 因为 Qthread 调用 quit() 并且这两个对象将被删除。这是下面的代码。
void TcpServer::incomingConnection(qintptr handle)
{
QThread* tcpThread = new QThread;
TcpSocket* tcpSocket = new TcpSocket;
tcpSocket->setSocketDescriptor(handle);
tcpSocket->moveToThread(tcpThread);
connect(tcpSocket,&TcpSocket::sigRecvFinish, [=](){
tcpThread->quit();
delete tcpSocket;
delete tcpThread;
});
tcpThread->start();
}
如何正确退出线程释放资源?同时,是什么导致了这个问题? 如果你能帮我解决这个问题,我将不胜感激。
您需要用以下代码替换您的 connect
:
connect( tcpSocket, &TcpSocket::sigRecvFinish, tcpSocket, &QObject::deleteLater );
connect( tcpSocket, &QObject::destroyed, tcpThread, &QThread::quit );
connect( tcpThread, &QThread::finished, tcpThread, &QThread::deleteLater );
首先 Qt 有很好的异步功能 API 所以线程的使用(在这种情况下)已经完全过时并且浪费资源。
通过在 connect 语句中使用 lambda,您失去了线程跳跃功能,这是默认由 connect
完成的。结果是您试图从该对象管理的线程中销毁线程对象。
请注意 QObject::connect last argument is: Qt::ConnectionType type = Qt::AutoConnection
(connections without lambda). When lambda is used QObject::connect 没有这样的功能,代码是从调用信号的线程调用的。
删除 lambda 将确保每次调用都在正确的线程上完成。
void TcpServer::incomingConnection(qintptr handle)
{
QThread* tcpThread = new QThread;
TcpSocket* tcpSocket = new TcpSocket;
tcpSocket->setSocketDescriptor(handle);
tcpSocket->moveToThread(tcpThread);
connect(tcpSocket, &TcpSocket::sigRecvFinish, tcpSocket, &QBject::delteLater);
connect(tcpSocket, &TcpSocket::sigRecvFinish, tcpThread, &QThread::quit);
connect( tcpThread, &QThread::finished, tcpThread, &QThread::deleteLater );
tcpThread->start();
}
有关技术细节,请参阅:
Constant Value Description Qt::AutoConnection
0
(Default) If the receiver lives in the thread that emits the signal, Qt::DirectConnection is used. Otherwise, Qt::QueuedConnection is used. The connection type is determined when the signal is emitted.