2009年7月29日

[ruby-list:46239] ruby1.8→1.9でprocess/thread関連でハマった話

永井@知能.九工大です.

ちょっと恥ずかしい話ですが,似たような状況でトラブルに合う方も
いらっしゃるかもしれないので書いておきます.(^_^;

ruby 1.8 で動いていたスクリプトを 1.9 で動かそうとした際の話です.
OS にも依存する話ですので述べておきますと,Linux 2.6.12, gcc 3.3.2 です.

スクリプトは,「fork して,終了時の後処理スレッドを動かして,
異常時には kill できるようにもしておく」というような,
まぁ,珍しくもない代物です.
例えば
---------------------------------------------------------------
pid = fork{ .... } # 子プロセス生成

Thread.new(pid){|child| # 後処理のための監視スレッドの生成
Process.waitpid(child)
... 後処理 ...
}

... Process.kill(:KILL, pid) # 異常時の kill
---------------------------------------------------------------
というようなもので,もちろん 1.8 では問題なく動いてました.

ですが,これは前述の OS 環境での 1.9 では動きません.

expert には自明のことなのかもしれませんが,
私の場合,その原因の解明にひどく時間がかかってしまいました.

# 実は RubyKaigi2009 の前から悩んでた.(^_^;

原因は
「ruby 1.9 では,Thread.new で作られる新しい thread は,
 新しい native thread として動作する.
 Linux 2.6.12, gcc 3.3.2 の環境では,新しい native thread には
 新しいプロセス番号が振られる.
 よって監視スレッドは fork を実行したプロセスとは別のプロセス番号を持ち,
 fork で生成されたプロセスの親プロセスとは認められなくなる.
 結果,Process.waitpid(child) は『そんな子プロセスは存在しないよ』の
 エラーで即座に抜けてしまう」
というものでした.

わかってしまえば「なぁんだ」というような話なのですが,
1.8 と 1.9 との間の非互換,OS 環境の差異による非互換として
心に留めておくべきことなのかもしれません.
--
永井 秀利 (nagai@xxxxx)
九州工業大学 大学院情報工学研究院 知能情報工学研究系 知能情報メディア部門


投稿者 xml-rpc : 2009年7月29日 18:33
役に立ちました?:
過去のフィードバック 平均:(0) 総合:(0) 投票回数:(0)
本記事へのTrackback: http://hoop.euqset.org/blog/mt-tb2006.cgi/86994
トラックバック
コメント
コメントする




画像の中に見える文字を入力してください。