パイプにデータがなく、書き込み側が閉じている場合、選択はパイプを読み取ることができることを示します。

パイプにデータがなく、書き込み側が閉じている場合、選択はパイプを読み取ることができることを示します。

私は読んでいます。Linuxプログラミングインターフェース

~から63.2.3 ファイル記述子はいつ準備されますか?、それは言う:

select()ファイル記述子を正しく使用するには、poll()ファイル記述子が準備状態を示す条件を理解する必要があります。 SUSv3では、O_NONBLOCKI / O関数への呼び出しがブロックされていない場合は、ファイル記述子(削除を含む)が準備されたと見なされます。関数が実際にデータを転送するかどうかに関係なく。イタリック体を強調表示:I / O操作がデータを正常に送信するかどうかではなく、ブロックされないかどうかをselect()示します。poll()これを念頭に置いて、これらのシステムコールがさまざまな種類のファイル記述子でどのように機能するかを考えてみましょう。この情報は、2つの列があるテーブルに表示されます。

  • このselect()列は、ファイル記述子が読み取り可能(r)、書き込み可能(w)としてマークされているか、または例外条件(x)があるかを示します。

....

パイプとFIFO

表 63-4 は、パイプまたは FIFO の読み出し側の詳細をまとめたものです。このData in pipe?列は、パイプが読み取ることができるデータが1バイト以上あるかどうかを示します。この表では、対応するフィールドPOLLINにが指定されていると想定しています。eventspoll()

....

表 63-4: パイプまたは FIFO の読み取り終了のためのselect()ガイドラインpoll()

Condition or event              | select()   | poll()
Data in pipe? | Write end open? |            
no            | no              | r          | POLLHUP
yes           | yes             | r          | POLLIN
yes           | no              | r          | POLLIN | POLLHUP

表63-5:パイプエンドまたはFIFO書き込みマークselect()(この表ではイベントフィールドに指定されていると仮定しています)poll()
POLLOUTpoll()

Condition or event                          | select()   | poll()
Space for PIPE_BUF bytes? | Read end open?  |            
no                        | no              | w          | POLLERR
yes                       | yes             | w          | POLLOUT
yes                       | no              | w          | POLLOUT | POLLERR

両方のテーブルの最初の行条件を理解していません。

パイプにデータがなく、書き込みの終わりが閉じています。select()これは、ファイル記述子が読み取ることができるファイル記述子という意味ですか?なぜ?select()パイプにデータがあるまでブロックしないでください。

バイト空間がなく、PIPE_BUF読み出し側が閉じています。select()これは書き込み可能なファイル記述子であることを意味しますか?

答え1

パイプ(読み取り側)を開いたと仮定すると、データはありません。しかし、書く方も開いています。この場合、次の操作はread()ブロックされ、select()FDは読み取り可能なものとして報告されません。私の考えでは、私たちはその点に同意したと思います。

今、あなたがこの詰まった部分にいて、read()作者がclose()パイプラインの一端にいると想像してみてください。どうしたの?read()結果は次のとおりです0。電話してもほぼ同じことが起こります。read() 後ろに作家closeだけをブロックしません。readすぐに結果とともに返されます0。したがって、あなたが引用したソースの推論によれば、あなたのFDは「読める」ということです。あるいは、select実際に報告された内容は「停止できません」と言う方が良いでしょう。

小さな例を書いてみると、この定義が実際に提案した「直感的な」定義よりもクリーンでエレガントなコードになることがわかります。

答え2

書き込み側が以前に開かれたことがない場合(たとえば、Linuxでは)、システムコールのselect(2)(およびpoll(2))はFIFOの読み取り側でブロックされます。

逆に、書き込み側が閉じた場合、PIPEの読み出し側もブロックされません。

違いは、FIFOは両端が閉じた状態で生成され、パイプが両端が開いた状態で生成されることです。 select(2) (および poll(2)) は、ブロック同期のみが存在した Unix の初期に発生したことを再現します (select(2) および BSD ソケット API が導入される前 - 一般に非ブロックが導入される前) Unix ) 。

書き込み側も開くまではFIFOの読み取り側を正常に開くことができないため、read(2)は常に書き込み側が開いているFIFOを探します。したがって、書き込み側が以前に開かれたことがない場合は、FIFOの読み取り側でselect(2)とpoll(2)の両方がブロックされることが論理的です(読み取り側がO_NONBLOCKで開かれている場合にのみ可能です)。

はい、表 63-4 の FIFO の LPI は、書き込み側が 1 回以上開いていて最後の作成者によって閉じられた場合にのみ正確です。

関連情報