河野真治 @ 琉球大学情報工学です。ま、良くある質問なんだけどさ。

In article <m3k79a2qaf.fsf@nightmare.hm.taito.co.jp>, Takahide Nojima <nojima@taito.co.jp> writes
> +-->B-->+
> |       |
> +---A---+
> #O_NONBLOCKとかはpipeだと何でかわからないのですが効いてくれないし、
> #read/writeのブロックについてはselect/alarm等のtime outで復活させる位
> #しか思い付けない...

まず、O_NONBLOCKは使ってはいけません。効かないってのは嘘です。
効きますよ。でも正しい設定の仕方は教えてあげない。何故かと言
うと、それを設定するとデータが落ちるからです。

read/write のブロックを防いでもいけません。必要だからブロッ
クされているのですから。select ループは必要なら使うことがで
きますが、結構大変です。expect とかを使う方がいいんじゃない
かな。Perl だったらopen2 or open3。

>  ものとします。つまり、プロセスBは、
>   ・どれだけ読みこんだら出力に出力するのか、また、
>   ・どれだけ出力したら読込みに転じるのか、
>  が全く不明なものとします。

それは構いませんが、必ず、

    プロセスBは、必要な入力を受け取った後、
    出力をcloseして正常終了する

ことは保証する必要があります。出力をcloseすれば十分です。
正常終了すれば出力はcloseされます。

問題は、Bの「必要な入力」の定義ですが、それはわかっているん
ですよね? 一般的には、こちらからそれを出力した後、pipeをclose
してやればOkです。逆に、close しないと、待ちに入ってしまうこ
とが多いと思います。そうなると、B/A でデッドロックすることに
なります。(きっと、これで悩んでいるのだと想像します)

そして、A の出力をバファリングしないように注意してください。
close すればだいたいOkなんですけどね。

Bが出力をcloseしない場合は、Aのreadはブロックしてしまいます。
そのような場合は、もう少しBに関する情報が必要です。

>  この時、名前無しpipeを2本作り、片方のpipeを使ってプロセスAから
> プロセスBへデータを出力し、同時にもう片方のpipeを使ってプロセスAが
> 再度受け取るというものを作ろうとしたと仮定します。

もし、B の出力を見ながらAの出力を調整するみたいなことをする、
つまり、Aの出力をcloseする前にBの出力を読み出すような場合だ
とすると、Bの出力のタイミングを知らずにdead lock を避けるこ
とは一般的にはできません。なので、select loopが必須となります。
その場合にも、必ず、B の出力がバッファリング無しであることが
必要です。

でも、まぁ、一度動けば、後は巨大な入出力とかが来ない限り
安定して動いていくれるようです。

---
Shinji KONO @ Information Engineering, University of the Ryukyus, 
              PRESTO, Japan Science and Technology Corporation
河野真治 @ 琉球大学工学部情報工学科, 
           科学技術振興事業団さきがけ研究21(機能と構成)