从外部等待特定调用的QObject(类似于QFuture的异步结果包装器)

时间:2013-01-14 18:01:24

标签: c++ qt asynchronous mutex thread-synchronization

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

0 个答案:

没有答案