私は今でもコンソール出力を使用して、自分のコードで何が起こっているかを把握しています。これは少し古い方法かもしれませんが、標準出力をログ ファイルなどに「パイプ」するためにもこれを使用します。
ただし、何らかの理由でコンソールへの出力が遅くなることが判明しました。コンソール ウィンドウへの fprintf() がブロックしているように見える理由を誰かが説明できるかどうか疑問に思っていました。
これまでに行ったこと/診断したこと:
必要な時間を簡単に測定しました
fprintf(stdout,"quick fprintf\n");
:0.82ms(平均)。vsprintf_s(...)
これは、同じ出力をわずか数マイクロ秒で文字列に書き込むため、長すぎると考えられています。したがって、コンソールに固有のブロッキングが必要です。ブロッキングから逃れるために
vsprintf_s(...)
、出力を fifo に似たデータ構造にコピーするために使用しました。データ構造は、クリティカル セクション オブジェクトによって保護されます。次に、別のスレッドが、キューに入れられた出力をコンソールに出力することにより、データ構造のキューを解除します。パイプ サービスの導入によって得られたもう 1 つの改善点。私のプログラムの出力 (コンソール ウィンドウに表示されるはずです) は、次のようになります。
- A
vsprintf_s(...)
は、出力を単純な文字列にフォーマットします。 - 文字列は、FIFO に似たデータ構造 (リンクされたリスト構造など) のキューに入れられます。このデータ構造は、クリティカル セクション オブジェクトによって保護されています。
- 2 番目のスレッドは、出力文字列を名前付きパイプに送信して、データ構造をデキューします。
- 2 番目のプロセスは、名前付きパイプを読み取り、文字列を fifo に似たデータ構造に再び配置します。これは、読み取りをコンソールへのブロック出力から遠ざけるために必要です。読み取りプロセスは、名前付きパイプの読み取りが高速で、パイプ バッファーのフィル レベルを継続的に監視します。
- その 2 番目のプロセスの 2 番目のスレッドは、最終的にデータ構造
fprintf(stdout,...)
をコンソールにデキューします。
- A
したがって、それぞれ少なくとも 2 つのスレッドを持つ 2 つのプロセスがあり、それらの間に名前付きパイプがあり、パイプの両側に fifo のようなデータ構造があり、パイプ バッファーがいっぱいになった場合のブロックを回避します。
これは、コンソール出力が「ノンブロッキング」であることを確認するための多くのものです。しかし、結果はそれほど悪くありません。私のメイン プログラムは、わずか数マイクロ秒で複雑な fprintf(stdout,...) を書き込むことができます。
多分私は以前に尋ねるべきだった: ノンブロッキングコンソール出力を持つ他の (より簡単な!) 方法はありますか?