web-dev-qa-db-ja.com

Qt 4.5-シグナルを発するのは関数呼び出しですか、それともスレッドですか?それはブロックしますか?

Qt 4.5の信号/スロットメカニズムの性質についてはわかりません。信号が発信されたとき、それはブロッキング関数呼び出しですか、それともスレッドですか?これ言ってみて

emit GrabLatestData();

// proceed with latest data

次の行に進む前に、すべての信号/スロットチェーンが解決されますか?

37
Extrakun

場合によります。 ドキュメント から:

信号が発信されると、通常の関数呼び出しと同様に、信号に接続されているスロットは通常すぐに実行されます。これが発生した場合、信号とスロットのメカニズムは、GUIイベントループから完全に独立しています。 emitステートメントに続くコードの実行は、すべてのスロットが返されると発生します。 キューに入れられた接続 ;を使用する場合、状況は少し異なります。このような場合、emitキーワードに続くコードはすぐに続行され、スロットは後で実行されます。

したがって、通常の場合は、同期およびブロッキングであり、キューに入れられた接続では非同期で非ブロッキングになります。

48
laalto

最大の問題は、あなたが知ることができないことです。つまり、クラスの観点から見ている場合です。放出しても、何が起こるかわかりません。

  • 信号に誰も接続されていない場合、何も起こりません
  • 同じスレッドの誰かがQt :: QueuedConnection以外のタイプを使用して接続されている場合、呼び出しはブロックされます
  • 同じスレッドの誰かがQt :: QueuedConnectionを使用して接続されている場合、呼び出しは非ブロッキングになります
  • 別のスレッドの誰かがQt :: DirectConnection(これを行うときは十分注意してください!)またはQt :: BlockingQueuedConnectionを使用して接続されている場合、呼び出しはブロックされます
  • 別のスレッドの誰かがQt :: AutoConnectionまたはQt :: QueuedConnectionを使用して接続されている場合、呼び出しは非ブロッキングになります

複数のオブジェクトが信号に接続されている場合に何が起こるかを知ることはさらに困難になります。その場合、他のスロットがまだキューに入れられている間に、いくつかのスロットが実行された可能性があります。ちなみに、非ブロッキング接続に関係するスレッドはありません。受信オブジェクトのスレッドのイベントループに投稿されるイベントのみがあります。

28
Ben

上記のlaaltoの答えは正しいです。ただし、もう1つのポイント:すべてのQObjectが同じスレッドに属し、キューに入れられた接続を手動で指定していない場合、信号に接続されたスロットの実行は同期的に行われます-すべての処理は、 'emitの後の次の行の前に実行されます'ステートメント。これが最も一般的なケースであるため、質問に対する答えは通常「はい」です。

複数のスレッドにわたるシグナルとスロット に関するドキュメントが役立つ場合があります。

9
Rob Knight