Я хочу написать класс (производный от QObject), который может ждать, пока кто-то вызовет определенную функцию. Этот класс будет затем использоваться для хранения результата асинхронной операции (за кулисами это удаленный вызов процедуры). Интерфейс класса должен выглядеть следующим образом:
class Result : public QObject
{
Q_OBJECT
public:
explicit Result(...);
signals:
void done();
public slots:
void setDone(const QVariant & result);
// blocking functions to receive the result
void waitForFinished();
QVariant result() { waitForFinished(); return _result; }
private:
QVariant result;
...
}
Конечно, этот класс должен быть потокобезопасной, означающий, что
setDone
Может быть, это можно сделать с помощью QFuture. Тем не менее, даже если это так, я также хочу реализовать такой механизм сам один раз для изучения синхронизации потоков в Qt. Если вы знаете, как это сделать с QFuture, вы можете оставить комментарий.
Я придумал следующее. Я также унаследовал от QMutex
иметь механизм, похожий на Java synchronize(this)
, Кроме того, я добавил bool _done
член:
void Result::Result(...) :
QObject(...),
_done(false)
{
}
void Result::setDone(const QVariant & result)
{
QMutexLocker synchronize(this);
_result = result;
_done = true;
emit done();
}
void Result::waitForFinished()
{
QMutexLocker synchronize(this);
if (!_done) {
QEventLoop loop;
connect(this, SIGNAL(done()), &loop, SLOT(quit()));
loop.exec();
}
}
Это правильная реализация?
Другое решение, которое придумал мой друг, — заблокировать мьютекс в конструкторе, отмечая результат. не должно быть сделано. В setDone
, разблокировать мьютекс, и в waitForFinished
используйте условие ожидания для ожидания разблокировки мьютекса. Я никогда не пользовалась QWaitCondition
так что я не знаю, делает ли это то, что я хочу.
Задача ещё не решена.
Других решений пока нет …