27

select(2)読み取りを監視しているファイル記述子が別のスレッドによって閉じられたときの関数の動作は何ですか?

いくつかの大まかなテストから、すぐに戻ります。結果は、(a) まだデータを待ち続けているが、実際にデータから読み取ろうとすると、EBADF が返される (おそらく競合が発生する可能性がある) か、(b) ふりをするかのいずれかであると思われます。ファイル記述子が渡されることはありませんでした。後者のケースが当てはまる場合、タイムアウトなしで単一の fd を渡すと、それが閉じられた場合にデッドロックが発生します。

4

4 に答える 4

23

いくつかの追加の調査から、dwcとbothieの両方が正しいようです。

質問に対するbotheの答えは、要約すると、未定義の動作です。これは、必ずしも予測できないことを意味するわけではありませんが、OSが異なれば動作も異なります。この場合、 SolarisやHP-UXのようなシステムが戻ってきたように見えますが、Linuxは2001年からのlinux-kernelメーリングリストへのこの投稿にselect(2)基づいていません。

linux-kernelメーリングリストの議論は、本質的に、依存するのは未定義の(そして壊れた)振る舞いであるということです。Linuxの場合、close(2)ファイル記述子を呼び出すと、その参照カウントが効果的に減少します。それselect(2)を参照する呼び出しもあるので、fdは開いたままで、戻るまで入力を待ちselect(2)ます。これは基本的にdwcの答えです。ファイル記述子でイベントを取得してから閉じます。fdがリサイクルされていないと仮定して、そこから読み取ろうとするとEBADFが発生します。(MarkRが彼の回答で行った懸念ですが、適切な同期があればほとんどの場合回避できると思います。)

だから、助けてくれてありがとう。

于 2009-02-19T17:09:17.503 に答える
7

ファイルの終わりに達したかのように動作することを期待します。つまり、ファイル記述子が準備完了として表示されますが、その後それを読み取ろうとすると「不良ファイル記述子」が返されます。

とにかく、それを行うことは非常に悪い習慣です.同じ番号の別のファイル記述子が、他の2番目のスレッドが閉じた直後にさらに別のスレッドによって開かれる可能性があるため、競合状態が常に発生する可能性があるため、選択中のスレッドは終了します.間違ったものを待っています。

ファイルを閉じるとすぐに、その番号が再利用可能になり、別のスレッドであっても、open()、socket() などの次の呼び出しで再利用される可能性があります。したがって、あなたは本当に、本当にこの種のことを避ける必要があります.

于 2009-02-12T21:59:52.660 に答える
3

何を聞かれているのか、ちょっとややこしい…

Select() は、「興味深い」変更時に返される必要があります。close() が参照カウントをデクリメントしただけで、ファイルがまだどこかに書き込むために開かれている場合、select() が起動する理由はありません。

他のスレッドが唯一の開いている記述子で close() を実行した場合は、さらに興味深いものになりますが、何かが本当に間違っているかどうかを確認するには、単純なバージョンのコードを確認する必要があります。

于 2009-02-12T22:13:07.917 に答える