Re: [Q] パイプで通信
河野真治 @ 琉球大学情報工学です。ま、良くある質問なんだけどさ。
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(機能と構成)
Fnews-brouse 1.9(20180406) -- by Mizuno, MWE <mwe@ccsf.jp>
GnuPG Key ID = ECC8A735
GnuPG Key fingerprint = 9BE6 B9E9 55A5 A499 CD51 946E 9BDC 7870 ECC8 A735