繁体   English   中英

了解如何在QThread中休眠/等待而不冻结事件循环

[英]Understanding how to sleep/wait in a QThread without freezing the event loop

环顾四周,我发现主要有3条建议来休眠QThread而不阻塞事件循环。 但是我不知道哪个是最有效的,或者我是否应该根据情况使用另一个。

有人可以解释我每个人发生了什么吗? 还有其他建议吗?

B类

#pragma once

#include <QtCore>
#include <QWaitCondition>
#include <QMutex>
#include <QEventLoop>
#include <QTimer>
#include <QDebug>

class ClassB : public QObject
{
    Q_OBJECT

public:
    ClassB()
    {
        qDebug() << "ClassB::ClassB";

        _timer = new QTimer(this);
        _timer->setInterval(100);
        QObject::connect(_timer, &QTimer::timeout, [this]() { emit continousSignalToClassA(); });
        _timer->start();
    }

    void start()
    {
        qDebug() << "ClassB::start";
        while(true)
        {
            switch (3)
            {
            case 1:
            {
                QThread::msleep(200);
                QCoreApplication::processEvents();
                break;
            }
            case 2:
            {
                QEventLoop loop;
                QTimer::singleShot(200, &loop, SLOT(quit()));
                loop.exec();
                break;
            }
            case 3:
            {
                QWaitCondition w;
                QMutex mutex;
                mutex.lock();
                w.wait(&mutex, 200);
                mutex.unlock();
                QCoreApplication::processEvents();
                break;
            }
            }
            qDebug() << "waiting";
        }
    }

signals:
    void continousSignalToClassA();

private:
    QTimer* _timer;
};

A类

#pragma once

#include <QThread>
#include <ClassB.h>

class ClassA : public QObject
{
    Q_OBJECT

public:
    ClassA() {}

    void launchClassBThread()
    {
        _classB = new ClassB();

        QObject::connect(this, &ClassA::startClassB, _classB, &ClassB::start);
        QObject::connect(_classB, &ClassB::continousSignalToClassA, this, &ClassA::signalReceived);

        QThread *thread = new QThread();
        _classB->moveToThread(thread);
        thread->start();
        emit startClassB();
    }
    void signalReceived()
    {
        qDebug() << "** I get a signal **";
    }

signals:
    void startClassB();

private:
    ClassB *_classB;
};

Main.cpp

#include <QCoreApplication>
#include <ClassA.h>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    ClassA classA;
    classA.launchClassBThread();
    return a.exec();
}

如果您想休眠QThread,请使用QThread::msleep(200); 并接受事件被阻止的事实。 使用QCoreApplication::processEvents(); 在大多数情况下,这是一个坏主意和设计缺陷。

如果要每隔N秒或毫秒执行一次函数,请使用QTimer::singleShot并删除所有自写循环。 这与QThread :: sleep(N)几乎相同,只是它不会阻塞事件循环,除非您在QTimer中有昂贵的阻塞代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM