1

fprintfシステムが IO ビジーでありながら CPU が大量にある場合、約 10 秒間不当にブロックされる呼び出しがあります。基になるストリームもsetvbuf、基になる fd を で開いたこともありませんO_DIRECT。これは、ストリームに stdio ストリームとシステム キャッシュの両方があることを意味します。

fprintfどうすればこんなに長い間通話がブロックされるのかわかりません. write(2)基になるストリームのストリーム バッファがいっぱいになるという最悪のケースでは、libc は単にバッファの内容をディスクに書き込むために呼び出すだけだと思います。しかし、私の知る限り、write(2)で開かれていない fdO_DIRECTでは、ディスク転送を待機しません。つまり、ディスク IO に関しては非同期です。したがって、時間のかかる作業は、書き込まれたデータに対してカーネルがキャッシュを割り当てることだけだと思いますが、システムがメモリ不足の場合でも、これは 10 秒の作業とは思えません。実際、システムには数十 MB の空きメモリと数 GB のメモリがキャッシュされています。

何かアドバイスはありますか?

ありがとう。

4

4 に答える 4

0

書き込み呼び出しは非同期ではありません。つまり、システム コールはカーネルから返される必要があります。もちろん、このシステム コールは、主に I/O キューにデータを置き、後で実際の転送を行います。ただし、この I/O キューはしばらくの間アクセスできない可能性があると思います。

これは、ブロック デバイスである限り、書き込み先のメディアとは無関係です。JPEG 画像のストリームを SD カードに書き込むプログラムがあります。このプログラムは、ハードディスク上で行われている操作のために動かなくなります。

ただし、書き込み呼び出しが 10 秒間ブロックされるという問題がある場合は、プログラムのトレースを試みることができます。あなたが観察しようとしている行動が、どのように、または妨げられるかどうかはわかりません

strace -T -e trace=write progname

ログのアクティビティを監視したい場合は、ログの書き込みをパイプまたは名前付きパイプにリダイレクトし、本質的にこのパイプから読み取り、ログファイルに書き込むプロセスを配置し、それを strace することができます。

于 2010-11-24T08:54:56.457 に答える
0

プロセスが大量のデータをディスクに書き込んでいる場合、ページ キャッシュに多数のダーティ ページが作成され、write()最終的にプロセスはそれらのページの一部に対して同期ライトバックを実行する必要があります。この状況では、適切な量のデータがディスクに書き出されるまで、カーネルはプロセスに戻りません (ただし、10 秒はまだ少し長く聞こえます)。

于 2010-11-25T05:27:14.823 に答える
0

ストリームで呼び出していないと言いsetvbuf()ましたが、ストリームはどのような種類のバッファリングを使用していますか? stderr使用しているストリームが(または場合によっては) でない限り、stdoutデフォルトでブロック バッファリングされます。つまり、バッファがいっぱいになるまで (通常は 4096 バイト以上)、書き込みは行われません。ログを書き込む頻度によっては、これにより 10 秒の遅延が発生する可能性があります。

だから私は試してみます:setvbuf(my_stream, NULL, _IONBF, 0);

編集: ...または、「ブロックされた」という言葉を完全に誤解した可能性があります。念のため、とにかく出発します。

于 2010-11-24T09:00:57.713 に答える
0

コードを複数のマシンで実行しましたか? もしそうなら、動作は同じですか?

そうでない場合は、システムのログでディスク アクセス エラーを確認してください。一度、同様の問題が発生し、その理由がディスクの障害でした。

于 2010-11-24T07:59:11.227 に答える