2012-04-03 4 views
4

状況は次のとおりです。Qt:信号をあまりにも速く送信するとどうなりますか?

  • バックグラウンドスレッドで1つの長期実行計算が実行されています。
  • この計算は、たとえば100msecごとにGUIエレメントをリフレッシュするように信号を送信しています。
  • それは100のそのような信号を送り出すとしましょう。
  • 再描画するウィジェットは、再描画するのに100ミリ秒以上かかります。 1秒と言いましょう。

イベントループではどうなりますか?信号がすべて実行されるまで(つまり100秒間)、信号は「積み上げ」をしますか?イベントを「落とす」メカニズムはありますか?

答えて

4

ユーザイベントは破棄されません。放出されたシグナルイベントを処理するよりも速くキューに入れると、メモリが足りなくなりプログラムがクラッシュするまで、イベントキューは大きくなります。 QTimerは、システムの負荷が大きい場合にタイムアウトイベントをスキップすることに注意してください。ある程度は、スループットを調整するのに役立ちます。

また、あるスレッドから別のスレッドにフィードバックを送信することも考えられます(おそらく確認応答)。消費者スレッドの遅れに基づいてプロデューサスレッドのタイミングを手動で調整することもできます。または、比喩的なスレッジハンマーを使用して、ブロックされたキュー接続に切り替えることができます。

3

この例では、ウィジェットで描画時間を測定できます。例えば、描画に240ミリ秒かかる場合は、何も描画せずに素早く次の2つの信号を処理することができます。そうすれば、信号は積み重なりませんでした。

編集:

は、実は私の解決策の若干の問題があります。最後のシグナルは常に再描画を引き起こすはずです。さもなければ、ウィジェットは計算が終了したときに間違ったデータを表示します。

シグナルがスキップされると、たとえば150 ms間隔でシングルショットタイマーを開始することができます。シグナルのために再描画が行われると、このタイマーは停止します。したがって、最後の再描画信号の後、この単一ショットタイマーは最終状態の描画を引き起こします。私はこれがうまくいくと思うが、それはかなり複雑になるだろう。

計算が開始されたときに再描画を行うための簡単なタイマーを起動すると、おそらくより良いアプローチになります。ウィジェットの描画に多くの時間がかかる場合は、描画時間に応じてタイマー間隔を動的に調整することができます。

+0

+1。私は、私が提案した何ものよりも、この種の解決策が好きだと思う。ただし、計算の頻度を図面の頻度からさらに切り離して完全に切り離すことができます。最後に出力された値をキャッシュし、タイマーに基づいて再描画します。 – cgmb

+0

最良のアプローチは本当にケースに依存します。 QTimerを使用した再描画は、再描画を常に実行する必要があり、再描画に時間がかかりすぎない場合は、簡単な解決策になります。しかし、通常、再描画がまったく必要ない場合、非常に重い再描画を必要とする変更のバーストがある場合は、私が提示した解決策がより良いかもしれません。 –

+0

私のソリューションに問題が見つかりました。答えにもう少しテキストを追加しました。 –

関連する問題