簡體   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