0

誰かが特定の関数を呼び出すのを待つことができるクラス (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したことがないので、これが私が望むものかどうかはわかりません。

4

0 に答える 0