簡體   English   中英

如何在Qt中停止線程

[英]How to stop threads in Qt

在Qt中停止線程的正確方法是什么?

假設我有一個工作程序( LicenseChecker類),並且我想在process成員函數中每n秒執行一些操作。 我需要無限期地進行操作,直到有人中止我的循環。

_worker = new LicenseChecker;
_thread = new QThread;
_worker->moveToThread(_thread);

connect(_thread, SIGNAL(started()), _worker, SLOT(process()));
connect(_worker, SIGNAL(finished()), _thread, SLOT(quit()));
connect(_worker, SIGNAL(finished()), _worker, SLOT(deleteLater()));
connect(_thread, SIGNAL(finished()), _thread, SLOT(deleteLater()));
connect(_worker, SIGNAL(newLicensesActivated(QVector<LicenseInfo>)),
                 this, SLOT(newLicensesActivated(QVector<LicenseInfo>)));

_thread->start();

我該怎么做才能中止它?

我想到的第一個想法是將sleep功能定義如下:

bool LicenseChecker::sleep(int seconds)
{
    QTime end_time = QTime::currentTime().addSecs(seconds);
    while (QTime::currentTime() < end_time)
    {
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);

        QMutexLocker lock(&_abort_sync);
        if (_abort)
        {
            return false;
        }
    }

    return true;
}

並在無限循環中檢查此函數的返回代碼:

while (true)
{
    if (!sleep(5))
    {
        emit finished();
        return;
    }

    // ...
}

然后在MainWindow的close事件上,我需要執行以下操作:

_worker->stop();
_thread->wait();

其中stop成員函數只是將_abort數據成員設置為true ,但是應用程序掛起了這些調用。

完成這項任務的正確方法是什么?

似乎您從另一個線程(主線程)調用stop() ,但工作程序實例位於工作程序線程中。 您可以通過仔細編寫如下內容以從另一個線程調用方法來克服此問題:

void Worker::stop()
{
    // make thread safe
    if(QThread::currentThread() != this->thread())
    {
        this->metaObject()->invokeMethod(this, "stop", Qt::QueuedConnection);
        return;
    }

    REAL CODE HERE ...
}

除此之外,我寧願使用計時器每n秒觸發一次許可證檢查。 這樣的事情(數據庫連接檢查器的示例):

dbCheckerThread = new QThread(this);
dbCheckerTimer = new QTimer();
dbCheckerTimer->setInterval(CHECKDBCONNECTIONINTERVALL);
dbCheckerTimer->moveToThread(dbCheckerThread);
dbChecker->moveToThread(dbCheckerThread);
connect(dbCheckerTimer, &QTimer::timeout, dbChecker, &DbConnectionChecker::checkConnection);
connect(dbCheckerThread, &QThread::started, dbCheckerTimer, static_cast<void (QTimer::*)(void)>(&QTimer::start));
dbCheckerThread->start();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM