#cpp #qt #многопоточность #qt_faq
Имеется поток, который иногда засыпает(QThread::sleep) на довольно продолжительное время (около 5 секунд). Если пользователь закрывает программу, то основной поток пытается завершить уснувший, и ожидает его действительного завершения с помощью функции QThread::wait. Но 5 секунд - достаточно продолжительное время, чтобы пользователь занервничал. В связи с этим вопрос: как разбудить поток, который внутри себя вызвал функцию QThread::sleep?
Ответы
Ответ 1
Qt не предоставляет средств для пробуждения спящего потока. Но вместо этого можно использовать класс QWaitCondition с некоторой доработкой. Напишем для этого специальный класс. WakeableSleep.h: #ifndef WAKEABLESLEEP_H #define WAKEABLESLEEP_H #include#include #include #include /** * @brief Класс, который позволяет временно усыпить поток с возможностью пробуждения из другого потока. * * Класс можно создать в любом потоке. При вызове метода \ref sleep поток приостанавливается * на время, переданное с параметром. При вызове метода \ref 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); }
Комментариев нет:
Отправить комментарий