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