我想写一个类(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
,所以我不知道这是否符合我的要求。