2013-04-02 11 views
13

systemへの呼び出しを使用して作成された子プロセスでルビプロセスを中断すると、ルビプロセス自体が中断されません。彼らは同じグループに属している必要がありますので、両方を中断する必要があります。これはruby2.0では無効です。ルビー1.8.7パッチ371、ルビー1.9.3パッチ392とruby2.0パッチ0を考えるとルビから呼び出された割り込みの子孫

bashでruby1.8 -e 'system "sleep 100"; p $?; sleep'を実行して^Cを押すとsleep 100にのみ、内部呼び出しを殺します。

Ruby 1.9は同じように動作します。

ruby2.0 -e 'system "sleep 100"; p $?; sleep'割り込み内部コマンドとルビープロセスitself.2.0.0-P0のソースを読む

--EDIT--

の両方を実行しているけど、私は取り扱いSIGINTSIGQUITSIGHUPがあることを見つけましたrb_syswaitメソッドで無視されました。これは、作成されたサブプロセスが終了するのを待ってからハンドラを復元します(rb_syswaitruby v1.8.7-p370ruby v1.9.3-p362、ブロッキングハンドラはruby v2.0.0-p0にありません)。

なぜsystemIO.popenの場合のみ、%x{}またはfork{}ではないのですか?

+0

実装の詳細またはこれを回避する方法を知りたいですか? –

+0

@SemyonPerepelitsa:both +通常の動作とみなされるべきもの – tig

+0

@SemyonPerepelitsaはなぜそれが行われたのか、最良の回避策ですか – tig

答えて

1

回避策として、SIGINTを自分自身で伝播できます。これは、あなたが指定されていませんでしたルビーが、お使いのオペレーティングシステムの問題ではないようです

ruby1.8 -e 'system "sleep 100"; p $?; Process.kill("INT",0) if $?.signaled?; sleep' 
+0

プロセスが割り込みを処理している場合は役に立ちません: 'ruby1.8 -e 'システム%q {ruby1.8 - e "Signal.trap(%q {INT}){exit};スリープ10"}; p $?; $ ?.シグナルがあればProcess.kill( "INT"、0);睡眠 ' – tig

+0

@tigそれは本当です。その場合、信号が子プロセスによって受信されたことを示すためには、別の方法(おそらく、子プロセス内の特別な終了コード)が必要になります。 –

+0

子Exitコード – tig

-1

:そうSIGINTを上げる場合は、システム・コマンドが原因信号に終了したかどうかを調べる、とすることができます。プロセスグルーピングと低レベルのシステムルーティングは、OSカーネルによって行われます。

+0

違いはrubyです、提供されたリンクでソースコードを比較してください – tig

+0

'strace'の下で両方のコマンドを実行し、出力を比較してください。おそらく、 'setpgid'はあるケースで呼び出され、他のケースでは呼び出されませんか? – dig

関連する問題