如何使用无限循环停止Qthread

How to stop QThread with infinite loop

本文关键字:Qthread 无限循环 何使用      更新时间:2023-10-16

我有用于数据接收的无限线程:

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应用程序。如果你们中有些人可以看一下它,并给出一些提示如何更好地组织它,我将非常感谢。

杀死/终止线程不应从外部完成,因为它可能导致数据损坏。甚至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;
}

当然不是最干净的设计等等,依此类推,但希望您明白;(

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。e。从mainwindow请求停止。

threadObject->requestInterruption();

需要很好地研究void QThread::terminate()的使用,只有在极少数情况下才能使用该功能。

或另一种方法是使用从另一个线程发送的停止信号,终止是停止线程的风险方法,我始终使用quit((然后wait((。