[ruby-list:49602] Re: IO.popen に不具合?
From:
尾川敏也 <ogw@...>
Date:
2013-09-25 13:02:03 UTC
List:
ruby-list #49602
尾川です。
リプライありがとうございます。
Tanaka Akira <akr@fsij.org> wrote:
> 原因は分かりませんが、とりあえずスレッドを join してみるのはいかがでしょうか。
> もしかしたらスレッド内でなにか例外が発生していて、
> join するとそれが可視化されるかもしれません。
恥ずかしながら、スレッドについては漠然としたイメージ程度しか知らな
いのですが、何か微妙なタイミング的なものがあるかもしれないと思って、
Ruby の公式サイトのマニュアルを見ながら、見よう見まねで少しだけ試し
てはありました。
あまり意味のある結果は得られなかったので書きませんでしたが。
# -----------------------------------------------------
class String
def |(cmdline)
IO.popen(cmdline, "w+") do |pipe|
t = Thread.fork { # t に受け取っておいて
pipe.write self
pipe.close_write
}
t.join # [A] ここで待ち合わせ
pipe.read
# [B] ここはさすがに無意味ですよね?
end
end
end
result = "".|("myprog1 datafile.txt").|("myprog2").|("myprog3")
# -----------------------------------------------------
[A] で join したときは単純にダンマリになってしまいました。
多分、[A] で join するということは、write が終わるまで read しない
ということなので、self のサイズが pipe のバッファより大きいとバッ
ファが一杯になり、でも誰も read してスペースを空けてくれないので、
write は書き残しを抱えてそのままブロックしている、のだろうと思いま
す。
[B] は、肝心の read が終わってから、ということは write が終わって
EOF を送ってからというタイミングなので、意味が無いだろうと思って試
していません。
[B] で join してみる意味はありますでしょうか?
あるいは他に試すとよいやり方などはありますでしょうか?
***
そういえば、関係があるかどうか判りませんが、こんな事もありました。
せっかちに pipe.read で一まとめに読み出そうなどとしているからマズイ
のかなと思って、pipe.read の替わりに、
# def |() の直後に result = "" しておいて
pipe.each do |s|
result << s
end
result
で1行ずつ小分けにして読んでみたら、Ruby が不気味なエラーメッセージ
を表示しました。
close された stream から読み出した
というような内容でした。read している最中に close する訳がないと思
うのですが、、、。
--
尾川敏也 ogw@shizuokanet.ne.jp
http://www6.shizuokanet.ne.jp/ogw/