8

ネイティブの win32 API を使用して Windows アプリケーションを作成しました。私のアプリは他のプロセスを起動し、出力をキャプチャして stderr 出力を赤で強調表示します。

これを実現するために、stdout と stderr 用に別のパイプを作成し、CreateProcess を呼び出すときに STARTUPINFO 構造体でそれらを使用します。次に、パイプから読み取り、出力をウィンドウに記録する stdout/stderr ハンドルごとに個別のスレッドを起動します。

ほとんどの場合、これで問題なく動作します。私が抱えている問題は、子プロセスが stderr と stdout にすばやく連続してログを記録すると、アプリが間違った順序で出力を表示することがあるということです。これは、2 つのスレッドを使用して各ハンドルから読み取ることが原因であると想定しています。

2 つを区別しながら、stdout と stderr を元の順序でキャプチャすることは可能ですか?

4

6 に答える 6

3

生成されたプログラムを作成してパケットに書き込み、それぞれにタイムスタンプを追加する以外には、それは不可能だと確信しています。それがなければ、通常、子プロセスの標準ライブラリで発生するバッファリングを計画できるため、パイプを介して親プロセスに送信されるまでに、それらがすでに故障している可能性が高くなります。

于 2009-10-10T21:01:22.810 に答える
2

私が見た stdout と stderr のほとんどの実装では、stdout はバッファリングされ、stderr はバッファリングされません。基本的にこれが意味することは、プログラムを直接コマンドラインで実行した場合でも、それらが正常に動作することが保証されていないということです。

http://en.wikipedia.org/wiki/Stderr#Standard_error_.28stderr.29

簡単な答え: cmd.exe に表示される順序は保証されていないため、cmd.exe に表示される順序と同じ順序で行を読むことは保証できません。

于 2009-10-12T15:41:53.137 に答える
0

目的は既存のプログラムの出力に注釈を付けることであるため、2つのストリームの可能なインターリーブは正しくなければなりません。元の開発者は、必須の順序が確実に守られるように、適切なflush()呼び出しを行います。

前に説明したように、タイムスタンプで書き込まれた各フラグメントを記録し、これを使用して、出力デバイスで実際に見られるシーケンスを復元します。

于 2009-10-12T18:30:57.567 に答える
0

それらをまったく分離しなくても、それらが正しい順序で相互に交換されるという保証はありません。

于 2009-10-11T16:41:48.503 に答える
0

stderr を stdout にリダイレクトできます。

command_name 2>&1

私が思い出したように、これはCでパイプを使用して可能です。

更新: 申し訳ありませんが、この 2 つを区別できるという部分を見逃していました。私は TextMate が何らかの形でユーザーに見えるコードを使用してそれを行ったことを知っています...しばらく見ていませんでしたが、ちょっと見てみましょう。しかし、さらに考えた結果、 Open3Ruby のようなものを使用できますか? と の両方STDOUTSTDERR同時に見る必要がありますが、実際には、これら 2 つの出力の特定の順序を期待するべきではありません。

更新 2: Ruby での意味の例:

require 'open3'

Open3.popen3('ruby print3.rb') do |stdin, stdout, stderr|
  loop do
    puts stdout.gets
    puts stderr.gets
  end
end

...どこにprint3.rbあるのですか:

loop do
  $stdout.puts 'hello from stdout'
  $stderr.puts 'hello from stderr'
end

出力を に直接投げる代わりにputs、オブザーバーにメッセージを送信して、プログラムでそれを出力することができます。申し訳ありませんが、このマシンには Windows (またはすぐに利用できるもの) がありませんが、これが概念を示していることを願っています。

于 2009-10-10T16:01:03.180 に答える
0

そうは思わないかもしれませんが、std_out はシステム設計者の管理下にあります。std_out がいつ、どのように書き込まれるかは、システム スケジューラの影響を受けます。私のテストでは、文書化されていない問題に従属しています。

ある日、何かを書いていて、エディターでコードを開いている間にシステム上のデバイスの 1 つでいくつかの作業を行ったところ、システムがドライバーにリアルタイムの優先順位を与えていることがわかりました。プロプライエタリ コードの約 10 分の 1 の重要度のコード。

書き込みの順序付けを取得するためにそれを再反転することは、控えめに言っても難しいでしょう。

于 2009-10-09T23:37:11.677 に答える