まず、シグナルとスロットの接続は、スレッド間ではなく、QObjects のシグナルとスロット間で行われます。QThread は QObject ですが、QThread から派生させるべきではありません。QThread から派生させないでください。問題ありません。
あなたがすることは次のとおりです。
1 つ以上の QThreadsを開始します(単に構築するだけではありません)。これらの QThreads は単なる Qt の基本クラスであり、それらから派生するものではありません。開始された raw QThread はブロックされ、イベントがそのイベント キューにポストされるのを待ちます。QThread::run()
呼び出しのデフォルトの実装QEventLoop::exec()
(または同等のもの)。したがって、これらのスレッドは、開始後、CPU サイクルを消費しません。
一連の QObject をインスタンス化します。必要に応じて、すべての信号/スロット接続を行います。
それらを呼び出して、これらのオブジェクトを 1 つ以上の QThreads に移動moveToThread(QThread*)
します。
ご覧のとおり、信号スロット接続の設定は通常の方法で行われ、特別な注意は必要ありません。Qt::DirectConnection
Qt は、スレッド間で QObject を移動するQt::QueuedConnection
ときに接続タイプを から に変更するなど、すべてを行います。
これらの QObject のメソッドを直接呼び出してはならないことに注意してください。別のスレッドから呼び出す可能性が高いため、アクセスがシリアル化されていないため、あらゆる種類の悪いことが起こります。以下のいずれかを実行する必要がありますが、これだけを、最速から低速の順に実行する必要があります。#3 は常に #4 より高速ですが、変化するので #2 と #3 の間でベンチマークを行う必要があることに注意してください。
カスタム イベントを QObject に投稿し、派生した QObject のcustomEvent(QEvent*)
メソッドで処理します。
シグナルスロット接続を使用し、QObjects のスロットに接続されたシグナルを送信します。
QMetaMethod::invoke
以前に検索したメソッドで使用します。メソッド ルックアップが事前に 1 回だけ行われるため、#4 よりも高速です。
を使用しQMetaObject::invokeMethod
ます。
QEvents を QObjects にポストすることは、シグナルスロット呼び出しを使用するよりも高速です。これは、呼び出されるコピー コンストラクターがなく、QEvent の構築時にユーザーが直接行う場合を除き、マーシャリングが行われないためです。
プロファイリング/ベンチマークにより、イベントの投稿が遅すぎることが示されている場合にのみ、 の使用を検討してQSharedMemory
ください。QThreads の数が多すぎると逆効果です。おそらく、システムの CPU コアの数を超えないようにする必要があります。単純にミューテックスやセマフォなどの同期プリミティブを使用すると、あまりにも多くのスレッドをコミットする必要があります。接続ごとに 1 つのスレッドを使用する必要はありません。Qt には、すでに使用しているイベント キューを使用して、各 QObject のイベント キュー ミューテックスが既にあります。