2013-04-02 3 views
13

Warum unterbricht Ruby-Prozess selbst mit Ruby-Prozess mit Kind unter Verwendung von Anruf erstellt zu system nicht unterbricht? Sie sollten zur selben Gruppe gehören, also sollten beide unterbrochen werden. Dies gilt auch nicht für ruby2.0.Interrupt Kind aus Ruby

Bei Rubin 1.8.7 Patch 371, Rubin 1.9.3 Patch 392 und ruby2.0 Patch 0:

Lauf ruby1.8 -e 'system "sleep 100"; p $?; sleep' in bash und drücken ^C tötet nur inneren Ruf zu sleep 100.

Ruby 1.9 verhält sich identisch.

Obwohl läuft ruby2.0 -e 'system "sleep 100"; p $?; sleep' Interrupts sowohl innere Befehl und Ruby-Prozess itself.2.0.0 -p0

--EDIT--

Lese Quellen Ich habe festgestellt, dass die Handhabung SIGINT, SIGQUIT und SIGHUP ist Switched in rb_syswait Methode ignoriert, die dann auf den erstellten Subprozess wartet und dann Handler wiederherstellt (rb_syswait in ruby v1.8.7-p370, ruby v1.9.3-p362 und ohne blockierende Handler in ruby v2.0.0-p0).

Warum ist es geschehen und warum nur für system und IO.popen, nicht %x{} oder fork{}?

+0

Möchten Sie Implementierungsdetails wissen oder wie funktioniert das? –

+0

@SemyonPerepelitsa: beide + was als normales Verhalten betrachtet werden sollte – tig

+0

@SemyonPerepelitsa jetzt nur, warum ist es getan und die besten Umgehungslösungen – tig

Antwort

1

Für eine Problemumgehung können Sie SIGINT selbst propagieren. Sie können prüfen, ob der Systembefehl aufgrund eines Signal verlassen, und wenn ja SIGINT erhöhen:

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

Hilft nicht, wenn Prozess Interrupts behandelt: 'ruby1.8 -e 'System% q {ruby1.8 - e "Signal.trap (% q {INT}) {exit}; Schlaf 10"}; p $ ?; Process.kill ("INT", 0) wenn $ ?. signalisiert ?; Schlaf'' – tig

+0

@tig Das ist wahr. In diesem Fall benötigen Sie einen anderen Weg (möglicherweise einen speziellen Beendigungscode im Kind), um anzuzeigen, dass ein Signal vom Kindprozess empfangen wurde. –

+0

Wird nicht helfen, wenn ich nicht kontrollieren kann, Kind Ausfahrt Code – tig

-1

Dies scheint nicht eine Frage von Ruby, aber das Betriebssystem zu sein, die Sie nicht angegeben. Prozessgruppierung und Low-Level-Systemrouting erfolgt durch den Betriebssystemkernel.

+0

Der Unterschied ist in Ruby, bitte vergleichen Sie den Quellcode unter den angegebenen Links – tig

+0

Führen Sie beide Befehle unter "strace" aus und vergleichen Sie die Ausgänge. Vielleicht wird 'setpgid' in einem Fall und nicht anders genannt? – dig