2016-05-22 1 views
1

read(2)へのコール中にENOBUFSまたはENOMEMを受信した場合、カーネルがリソースを解放し、将来のコールが成功する可能性はありますか?または、エラーを致命的なものとして扱い、ティアダウンプロセスを開始しますか?read(2)の呼び出し時にENOBUFS/ENOMEMが発生したときはどうしますか?

+1

公式に推奨されている動作は何か分かりませんが、プログラミングではこの問題を突き抜けて、ENOBUFSエラーが一時的であることがわかりました。つまり、私がread()を再度呼び出すと、それは成功するでしょう。 YMMV。 –

答えて

1

私は少し迷って、再試行の可能性があるかどうかを確認します。

ENOMEMを読んだら読むと、カーネルが深刻な問題になっていることを意味します。はい、再試行が可能かもしれませんが、そうでない可能性もあります。そうでない場合は、再試行するまでどれくらい待つのが適切ですか?直ちに再試行すると、100%CPUバウンドループを行っている別のプロセスを追加しないようにするにはどうすればよいですか?

個人的には、私がエラーを処理する方法を知っている読者からこのようなエラーが出た場合、私はいつものようにエラーを処理します。私が積極的に読書が成功する必要がある状況であれば、私はプログラムに失敗するでしょう。このプログラムがミッションクリティカルな場合は、それを再起動するウォッチドッグの中で実行する必要があります。

カーネルがENOMEMを返すと、OOMキラーが誰かにSIGKILLを送るという過失ではないことに注意してください。体験は、誰かがあなたのプロセスになる可能性が高いことを示しています。これは、ただ終了するもう一つの理由です。プロセスを監視しているウォッチドッグでその終了を処理します(ただし、OOMキラーがトリガーされた場合、ウォッチドッグはSIGKILLを取得する可能性があります)。

ENOBUFSの状況はあまり変わりません。 「どのくらいの時間を遅延させるか」と無限ループの問題は依然として存在します。 OOMキラーはそのような考慮事項の下ではあまりありませんが、ウォッチドッグに頼っても正しい経路、IMHOです。

ここでのコアの問題は、特定のケースがないことです。read(2)のいずれかのエラーを返します。これらのエラーが発生する状況が発生した場合、ドライバがEIOを返すのとまったく同じです。

このように、OPが特定のユースケースを知っていなければ、彼のコードは処理するために作成されていますが、これらのエラーは本当に同じように処理する必要があります。

最後にOOMキラーに関する1つではありません。人々は時々、それをシステム全体をぶら下げないようにするものと考えています。それは事実ではありません。 OOMキラーランダムにがプロセスを殺します。プロセスのページが増えるほど、それが殺される可能性が高くなることは事実です。しかし、私はその事実に頼ることは絶対に勧めません。

物理メモリが枯渇し、OOMキラーがメモリをほとんど使用していないプロセスを犠牲にし、主な犯人になるまでに時間がかかるケースがあります。私は、メモリが枯渇したことがカーネルのアドレス空間にあり、ユーザ空間のプロセスが完全にランダムであったというケースを見てきました。

私が上記のように、OOMキラーはあなたのウォッチドッグプロセスを殺して、あなたのメインホーガーを走らせるかもしれません。コードパスを修正するためにそれに頼らないでください。

+0

'ENOBUFS'についてはどうですか?あなたの答えは、質問に対するコメントと相反すると思われる。私は可能な限り信頼できるアプリケーションを作成しています。プレッシャーがかかっているので終了したくないので、それが絶対に唯一の行動であれば終了したいと思っています。私はネットワークサービスを書いています。待っていてもそれほど問題ではありません。あなたが言及しているように、私はむしろ、私のプロセスが存在するかどうかの権限であると思われるので、実際に物事を引き裂くために 'SIGKILL'が待っています。 – dcow

+0

@dcow、あなたは実際にそれらのエラーを取得しましたか? "read"のmanページはそれらを可能なリターンコードとしてリストしていないので、特定のFSドライバまたはカスタムキャラクタデバイスのためだけにそれらを取得すると思います。 –

+0

@dcow、あなたのフォローしている質問を詳述するための編集された答え。 –

関連する問題