Имеется поток, который иногда засыпает(QThread::sleep) на довольно продолжительное время (около 5 секунд). Если пользователь закрывает программу, то основной поток пытается завершить уснувший, и ожидает его действительного завершения с помощью функции QThread::wait. Но 5 секунд - достаточно продолжительное время, чтобы пользователь занервничал. В связи с этим вопрос: как разбудить поток, который внутри себя вызвал функцию QThread::sleep?
Ответ
Qt не предоставляет средств для пробуждения спящего потока. Но вместо этого можно использовать класс QWaitCondition с некоторой доработкой. Напишем для этого специальный класс.
WakeableSleep.h:
#ifndef WAKEABLESLEEP_H
#define WAKEABLESLEEP_H
#include
ef sleep поток приостанавливается
* на время, переданное с параметром. При вызове метода
ef wake из другого потока целевой
* поток возобновляет выполнение независимо от истекшего времени.
* \threadsafe
*/
class WakeableSleep : public QObject
{
Q_OBJECT
public:
explicit WakeableSleep(QObject *parent = 0);
/**
* @brief Усыпить текущий поток на milleseconds миллисекунд.
* @param milliseconds Время сна.
*/
void sleep(quint32 milliseconds);
/**
* @brief wake Пробудить целевой поток из другого потока.
*/
void wake();
private:
QMutex mutex;
QWaitCondition waitCondition;
};
#endif // WAKEABLESLEEP_H
WakeableSleep.cpp:
#include "wakeablesleep.h"
WakeableSleep::WakeableSleep(QObject *parent) :
QObject(parent){}
void WakeableSleep::sleep(quint32 milliseconds)
{
mutex.lock();
waitCondition.wait(&mutex, milliseconds);
mutex.unlock();
}
void WakeableSleep::wake()
{
mutex.lock();
waitCondition.wakeAll();
mutex.unlock();
}
Теперь вместо метода QThread::sleep можно использовать методы этого класса следующим образом:
WakeableSleep sleeper;
void Thread1()
{
sleeper.wake();
}
void Thread2()
{
sleeper.sleep(5000);
}
Комментариев нет:
Отправить комментарий