我想编写一个可以等待某人调用特定函数的类(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();
}
}
这是一个正确的实现吗?
我的一个朋友想出的另一个解决方案是将互斥锁锁定在构造函数中,将结果标记为not be done。在setDone
中,解锁互斥体,并waitForFinished
使用等待条件等待互斥体解锁。我从未使用过QWaitCondition
,所以我不知道这是否符合我的要求。