こんにちは.きたです.

> |のように,GC で回収させると pipe は close されますが,子プロセスは
> |wait されないようです.
> 
> おっしゃる通り、プロセスのwaitは行っていません。というのはた
> だでさえ「遅い遅い」と文句が出ているGC の最中にwaitでブロッ
> クしてしまうのは避けたいからです。

なるほど.そういうことだったのですね.納得.

ところで,リファレンスマニュアルや Ruby の落とし穴や FAQ を探したので
すが,「GC では wait しない」という記述は見つけられませんでした.

サーバプロセスなど長時間常駐するようなスクリプトで

  open("|hoge").each do |l|
     ...
  end

このように書いてしまうと,ゾンビプロセスが大量生成されてしまうことにな
るので,落とし穴あたりに記述してあってもよいのではないかと思うのですが,
いかがでしょうか?
# というか誰が書き込んでも良いのかな?


> より望ましい実装の提案はい
> つもお待ちしています。

まつもとさんが気にされているのが
1.まだ終了していない子プロセスを wait で延々待つのはイヤだ
2.そもそも wait というシステムコールのコストは高いので GC の中では
   wait したくない
のどちらなのか分かりませんが,1 のほうであれば MUSHA さんのおっしゃる
とおり WNOHANG で waitpid が現実的だと思います.

でも,現在の io.c では,ある IO オブジェクトに関連する子プロセスの pid
は fptr->pid に格納されていますよね.
GC 時にまだ子プロセスが exit していなくて waitpid が 0 を返した場合,
その pid を誰が覚えておくのが適当なんでしょうね?
io.c の中に static な配列があって,そこで覚えておく?

2 の方であれば,waitpid 使おうがなんだろうが同じなのでどうしようもない
ですね.