繁体   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