web-dev-qa-db-ja.com

コンソール用のバッファを設計するにはどうすればよいですか?

問題

インタープリターから出力を受け取るグラフィカルコンソールウィジェットがあります。残念ながら、コンソールは出力をリアルタイムでペイントするほど高速ではありません。そのため、コンソールへの書き込みを5ms遅らせるバッファ(FIFOスレッドセーフキュー)を実装する必要がありました。したがって、通常1000印刷のループが1ミリ秒未満で実行される場合、すべてを印刷するには5000ミリ秒かかります。

バッファのシーケンス図:

Sequence diagram for a time delayed buffersendCode:インタープリターがコンパイルして実行できるコードを送信します。

writeLine:インタープリターからの出力をバッファーに書き込みます。

startTimer:5ミリ秒ごとにタイムアウトするタイマーを開始します。

getLine:バッファーから最も古い行を取り出します。 5msごとに呼び出されます。

line:コンソールに送信されて表示される行。

必要なもの

現在のところ、出力を遅延させるこの戦略は機能しますが、リアルタイムのソリューションが必要な場合はあまり実用的ではありません。バッファサイズを設定する方法がもう1つあります。次に、バッファサイズに達したら、出力をフラッシュします。ラインがブロックで送信されていることを考慮してコンソールが窒息しないので、これははるかに優れた戦略です。

しかし、問題は、バッファサイズをたとえば50行に設定した場合、50行が印刷されるまでユーザーに出力が表示されないことです。バッファサイズを小さくしても、コンソールへのストレスを減らすことを目的としているため、実際には効果がありません。

どのようにすれば、コンソールが死ぬことなく出力がリアルタイムで出力されるようにバッファシステムを作成できますか

3
daegontaven

ウィキティのコメントの骨にもっと肉を加えるため。

固定サイズのバッファーとn msに設定されたタイマーが必要です。

  1. バッファにコードを書き込むときに、バッファが空の場合は、タイマーをnミリ秒に(再)開始します。

  2. バッファーに書き込んでバッファーがいっぱいになった場合は、バッファーをコンソールにフラッシュし、バッファーをクリアしてタイマーを停止します。

  3. タイマーが時間切れになり、バッファにコードがある場合は、コンソールにフラッシュし、バッファをクリアして、タイマーを停止します。

  4. タイマーが時間切れになり、バッファにコードがない場合は、タイマーを停止します。

このアルゴリズムで十分です。バッファサイズとタイマーの遅延のバランスをよくしてコンソールの操作を最もスムーズにするには、試行錯誤が多少必要になる場合があります。必ずしも必要ではありませんが、フラッシュ/クリア/ストップを手動フラッシュ機能として利用できるようにすることで、多少のメリットが見つかることもあります。

8
Alex

スレッドセーフキューが必要ですFIFOデータコレクション(ロックまたはライブラリ経由で自作))。これにより、オーバーフローが発生した場合にバッファー内の最初のメッセージが削除されます。UI||コンソールスレッドは、データ構造と、印刷するものがある場合はすべてをポップします(バッファーにデータがあります)->バッファーがいっぱいになるまで待機しないでください。

すべてのメッセージには、入力された場所のタイムスタンプと優先度が含まれています。タイムスタンプとともに古いメッセージをすべて破棄します。

さらに、コンソールのバッファーサイズを増やします。 printf()またはそのラッパーへの呼び出しが多すぎるために死ぬコンソールは知りません。

0
Git