QWaitCondition

Автор: | 5 августа, 2019

QWaitCondition позволяет потоку сообщать другим потокам о выполнение каких-либо условий. Один или несколько потоков могут блокировать ожидание QWaitCondition для установки условия с помощью wakeOne() или wakeAll().

Рассмотрим небольшой пример который позволяет увидеть механизм ожидания. В данном примере происходит запуск потока и установка его в ожидание. При нажатии на клавишу происходит снятия ожидания в дальнейшего его продолжение работы.

Пример использования QWaitCondition

Полный листинг:

// функция main
#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}
// основной класс
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

      mThread1 =  new  QThread_1 (&mMutex,&mWait);
// запуск потока в ожидании
      mThread1->start();
// по нажатие на кнопку возобновление работы
      connect(ui->pushButton,SIGNAL (clicked()),this,SLOT(mutexWake()));
}



// корректное завершение потока если он находится в режиме ожидания
MainWindow::~MainWindow()
{

    if (mMutex.tryLock())
    {
         mMutex.unlock();
    }

    mThread1 ->deleteLater();
    mThread1->wait();
    delete mThread1;
    delete ui;

}


void MainWindow::mutexWake()
{
    mWait.wakeOne(); // возобновление работы потока
}
// описание  основного класса
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMutex>

#include "qthread_1.h"

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();


private:
    Ui::MainWindow *ui;
    QMutex mMutex;
    QThread_1 * mThread1;
    QWaitCondition  mWait;

private slots:
     void mutexWake();

};

#endif // MAINWINDOW_H
// класс потока
#include "qthread_1.h"

QThread_1::QThread_1(QMutex*m, QWaitCondition * w)
    :mutex(m), waitMutex(w)
{

}


void QThread_1::run()
{
   qDebug () << "run";
   QMutexLocker locker (mutex);
   waitMutex->wait(mutex);
   qDebug () << "exit";
}
// описание класса потока
#ifndef QTHREAD_1_H
#define QTHREAD_1_H

#include <QObject>
#include <QThread>
#include <QMutex>
#include <QWaitCondition>
#include <QDebug.h>

class QThread_1 : public QThread
{
    Q_OBJECT
public:
    QThread_1 (QMutex*,QWaitCondition*);


private:
    QMutex * mutex;
    QWaitCondition * waitMutex;

protected:
    void run();
};

#endif // QTHREAD_1_H

Поток запустится сразу при начале работы программы

При запуске данного фрагмента сначала выведется:

qDebug () << «run»;

После нажатия на кнопку:

qDebug () << «exit»;