我有无限的数据接收线程:
void RxFTDI::process() {
qDebug() << "RxFTDI hello!" << QThread::currentThreadId();
while(true)
{
FT_GetStatus(ftHandle,&RxBytes,&TxBytes,&EventDWord);
// FT_GetQueueStatus(ftHandle, &RxBytes);
if ((ftStatus == FT_OK) && (RxBytes > 0))
{
// qDebug() << "rx " << RxBytes;
FT_Read(ftHandle, &RxBuffer, RxBytes, &BytesReceived);
if (ftStatus == FT_OK) {
// FT_Read OK
}
else {
// FT_Read Failed
}
}
}
}
当我想用delete RxThread;
删除该帖子时,我的应用程序看起来崩溃了:
bool Ftdi::quitRxTxThreads ()
{
emit Tx->finished();
emit Rx->finished();
delete Tx;
delete Rx;
RxThread->terminate();
TxThread->terminate();
delete TxThread;
delete RxThread;
return true;
}
完整项目在github上:https://github.com/bLLAZ/ftQt 这个想法很简单。 GUI +两个独立的线程:Tx和Rx。这是我的第一个Cpp应用程序。如果你们中的一些人可以看一看并给出一些提示如何更好地组织它,我真的很感激。
答案 0 :(得分:6)
杀死/终止线程不应该从它外部完成,因为它可能导致数据损坏。甚至Qt文档都说明了这一点:
警告:此功能很危险,不鼓励使用。该 线程可以在其代码路径中的任何位置终止。线程可以 修改数据时终止。线程没有机会 自行清理,解锁任何固定的互斥锁等。简而言之,使用 只有绝对必要时才能使用此功能。
那该怎么办?我想你可以在线程之间使用变量共享来像这样优雅地完成它们。在课堂上放一些标志:
public:
atomic<bool> finish = false;
然后,改变过程:
void RxFTDI::process() {
qDebug() << "RxFTDI hello!" << QThread::currentThreadId();
while(!finish.load(std::memory_order_relaxed))
{
FT_GetStatus(ftHandle,&RxBytes,&TxBytes,&EventDWord);
// FT_GetQueueStatus(ftHandle, &RxBytes);
if ((ftStatus == FT_OK) && (RxBytes > 0))
{
// qDebug() << "rx " << RxBytes;
FT_Read(ftHandle, &RxBuffer, RxBytes, &BytesReceived);
if (ftStatus == FT_OK) {
// FT_Read OK
}
else {
// FT_Read Failed
}
}
}
}
最后运行线程的函数:
bool Ftdi::quitRxTxThreads ()
{
emit Tx->finished();
emit Rx->finished();
delete Tx;
delete Rx;
RxThread->finished.store(true, std::memory_order_relaxed);
TxThread->finished.store(true, std::memory_order_relaxed);
//now wait for them to finish
RxThread->wait();
TxThread->wait();
delete TxThread;
delete RxThread;
return true;
}
当然,它不是最干净的设计等等,但希望你能得到这个想法;)
答案 1 :(得分:3)
从Qt 5.2开始,有2个新功能。
bool QThread::isInterruptionRequested() const
void QThread::requestInterruption();
在你的主题中你可以拥有一个永远运行的函数并检查isInterruptonRequested
void long_task() {
forever {
if ( QThread::currentThread()->isInterruptionRequested() ) {
return;
}
// run your tasks
}
}
当你想要完成时,你可以使用线程对象,i。即从MainWindow请求停止。
threadObject->requestInterruption();
需要非常好地研究void QThread::terminate()
的使用,并且只有在极少数情况下才能使用该函数。
答案 2 :(得分:1)
或者另一种方式是使用从另一个线程发送停止信号,终止是一种有风险的方法来停止一个线程,我总是使用quit()然后wait()。