2013-04-02 1 views
13

Pourquoi interrompre le processus ruby ​​avec un enfant créé en utilisant l'appel à system n'interrompt pas le processus ruby ​​lui-même? Ils devraient appartenir au même groupe, donc ils devraient tous les deux être interrompus. De plus, ceci n'est pas valide pour ruby2.0.Interrompre l'enfant appelé à partir de ruby ​​

Compte tenu de rubis 1.8.7 Patch 371, rubis 1.9.3 Patch 392 et patch ruby2.0 0:

Exécution ruby1.8 -e 'system "sleep 100"; p $?; sleep' en bash et en appuyant sur ^C ne tue que l'appel intérieur à sleep 100.

Ruby 1.9 se comporte de manière identique.

Bien que l'exécution ruby2.0 -e 'system "sleep 100"; p $?; sleep' interruptions à la fois intérieure et commande processus ruby ​​itself.2.0.0-p0

--EDIT--

sources lecture que j'ai trouvé que la manipulation SIGINT, SIGQUIT et SIGHUP est commuté à ignoré dans la méthode rb_syswait qui attend que le sous-processus créé se termine et restaure les gestionnaires (rb_syswait dans ruby v1.8.7-p370, ruby v1.9.3-p362 et sans bloquer les gestionnaires dans ruby v2.0.0-p0).

Pourquoi est-il fait et pourquoi seulement pour system et IO.popen, pas %x{} ou fork{}?

+0

Voulez-vous connaître les détails de mise en œuvre ou comment contourner ce problème? –

+0

@SemyonPerepelitsa: les deux + ce qui devrait être considéré comme un comportement normal – tig

+0

@SemyonPerepelitsa maintenant seulement pourquoi est-ce fait et meilleures solutions de contournement – tig

Répondre

1

Pour une solution de contournement, vous pouvez propager SIGINT vous-même. Vous pouvez vérifier si la commande du système est sorti en raison d'un signal, et le cas échéant soulever SIGINT:

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

Ne aide pas si le processus gère les interruptions: 'ruby1.8 -e 'système% q {ruby1.8 - e "Signal.trap (% q {INT}) {exit}; dormez 10"}; p $ ?; Process.kill ("INT", 0) si $ ?. est signalé ?; sleep'' – tig

+0

@tig C'est vrai. Dans ce cas, vous auriez besoin d'un autre moyen (peut-être un code de sortie spécial dans l'enfant) pour indiquer qu'un signal a été reçu par le processus fils. –

+0

N'aidera pas si je ne peux pas contrôler le code de sortie de l'enfant – tig

-1

Cela ne semble pas être une question de Ruby, mais votre système d'exploitation, que vous n'avez pas spécifié. Le regroupement de processus et le routage système de bas niveau sont effectués par le noyau du système d'exploitation.

+0

La différence est en ruby, veuillez comparer le code source aux liens fournis – tig

+0

Exécutez les deux commandes sous 'strace' et comparez les sorties. Peut-être, 'setpgid' est appelé dans un cas et pas l'autre? – dig