2012-02-13 15 views
0

はい、できません。 istreamはファイルの終わりを検出できるので、奇妙なostreamはクローズしていないようです。cerrを閉じるには

私の状況です:このプロセスでは、Posix fd2のすべての出力をパイプで作成し、パイプ出力をfd2にdup2することでキャプチャしています。次に、スレッドは関連するCストリームを使用してパイプの読み込み終了を読み取ります(そして、関連する別のCストリームを介して元のfd2にタイムスタンプを付けて各行を書きます)。

すべての子が死んでいるとき、私はcerrに終了メッセージを書きます。それを元のエラーファイルにエコーしているスレッドがパイプを閉じて終了するように、私はそれを閉じる必要があります。

stderrとfd2の両方をクローズしていても、スレッドはeof()を検出していません。

私は単純なものを使ってメインプログラムを複製し、C++のiostreamsの代わりにCストリームを使用していますが、すべてがstderrをfclosingするだけでうまくいきます(単純化されたテストでは子プロセスはありません)。

編集:hmm ..チャンネル2にdup2'ingした後、元のパイプfdを閉じる必要がありますか?私はそれをしなかったので、根底にあるパイプには依然として開いたfdが付いています。ああ..それは答えです!

+0

あなたはLinuxでstdioストリームを終了し、ウィンドウ上で '^ Z'を終了すると思います。 –

+0

' ostream'のすべてがファイルベースではありません(例えば 'std :: ostringstream'など)ので、あなたは 'ostream'上にインタフェースのようなファイルを持っていないということです。 –

+0

あなたは正しいですが、その後、近くにあるものにリダイレクトされても、cerrを閉じることができないという奇妙なことがあります。しかし、私は基礎となるCストリームとファイル記述子を閉じています。パイプのもう一方の端の読み込みはfdopenされたCストリームを使用しています。 – Yttrill

答えて

1

ファイルディスクリプタをdup2で複製すると、もとのディスクリプタは元のファイルへの有効な参照のままです。特定のファイルに関連付けられているすべてのファイル記述子が閉じられるまで(close)、ファイルは閉じられず、関連付けられたリソースが解放されます。

あなたがよく知られている番号( stderr用など2)にファイルディスクリプタをコピーする dup2を使用している場合は、あなたは通常、すぐに成功した dup2後に元のファイルディスクリプタに closeを呼びたいです。

0

ベストは、リソースの周りにラッパーを配置し、デストラクターがスコープから外れたときに閉じるようにすることです。 Bjarne Stoustupのプレゼンテーション

+0

C++でレッスンは必要ありません。パイプにリダイレクトされたcerr/stderr/2ファイルを閉じる方法を理解する必要があります。読み取り側はeofを見ることができます。 – Yttrill

1

標準のC++ストリームに使用されるストリームは、対応するstdioファイルによって制御されるものと同じです。つまり、fclose(stderr)の場合は、std::cerrのストリームを閉じることもできます。 ...そしてあなたは様々なdup()の機能で遊ぶように見えるので、close(2)でもこのストリームを閉じることができます。

+0

投稿を読んでください。私はstderrと2の両方を閉じます。それは助けになりません。 – Yttrill

+0

'fclose(stderr)'または 'close(2)'を実行すると、ファイル記述子が明確に閉じられます。これらのいずれかが失敗したかどうかを確認したいかもしれませんが、 'popen()'ファイルではこれは起こりそうにないと思います。クローズメッセージが送られていることを確認するために、ストリームをフラッシュする必要があるかもしれませんが、 'std :: cerr'は通常、すべての出力(' std :: unitbuf'を使って)後に自動的にフラッシュするように設定されています。つまり、あなたの問題はストリームの閉鎖ではなく、読書の終わりである可能性があります。 –

+0

ファイルディスクリプタで何をしているのか不明な質問が出てきます。終了しようとしているスレッドが実際にこのストリームに書き込んでいますか?もしそうであれば、ストリームに実際に何かが書き込まれない限り、ストリームが実際に閉じられたことを検出しません。 –

関連する問題