如何使用无限循环停止QThread

时间:2018-02-15 16:24:48

标签: c++ qt

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

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应用程序。如果你们中的一些人可以看一看并给出一些提示如何更好地组织它,我真的很感激。

3 个答案:

答案 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()。