2013-04-02 16 views
13

Perché interrompere il processo ruby ​​con child creato utilizzando la chiamata a system non interrompe il processo ruby ​​stesso? Dovrebbero appartenere allo stesso gruppo, quindi dovrebbero essere entrambi interrotti. Inoltre, questo non è valido per Ruby2.0.Interrupt child called from ruby ​​

Dato rubino 1.8.7 patch di 371, ruby ​​1.9.3 patch di 392 e ruby2.0 patch di 0:

esecuzione ruby1.8 -e 'system "sleep 100"; p $?; sleep' in bash e premendo ^C uccide solo chiamata interiore a sleep 100.

Ruby 1.9 si comporta in modo identico.

Sebbene esecuzione ruby2.0 -e 'system "sleep 100"; p $?; sleep' allarmi sia di comando interno e processo rubino itself.2.0.0-p0

--EDIT--

lettura fonti ho trovato che il trattamento SIGINT, SIGQUIT e SIGHUP è passato a ignorato nel metodo rb_syswait che attende il completamento del processo secondario creato e quindi ripristina i gestori (rb_syswait in ruby v1.8.7-p370, ruby v1.9.3-p362 e senza bloccare i gestori in ruby v2.0.0-p0).

Perché si fa e perché solo per system e IO.popen, non %x{} o fork{}?

+0

Vuoi conoscere i dettagli dell'implementazione o come risolvere il problema? –

+0

@SemyonPerepelitsa: entrambi + cosa dovrebbe essere considerato comportamento normale – tig

+0

@SemyonPerepelitsa ora solo perché è fatto e le soluzioni migliori migliori – tig

risposta

1

Per una soluzione alternativa, è possibile propagare autonomamente SIGINT. È possibile verificare se il comando di sistema è uscito a causa di un segnale, e se è così aumentare SIGINT:

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

Non aiuta se il processo sta gestendo gli interrupt: 'ruby1.8 -e 'system% q {ruby1.8 - e "Signal.trap (% q {INT}) {exit}; sleep 10"}; p $ ?; Process.kill ("INT", 0) se $ ?. segnalato ?; sleep'' – tig

+0

@tig Questo è vero. In tal caso, sarebbe necessario un altro modo (forse un codice di uscita speciale nel bambino) per indicare che un segnale è stato ricevuto dal processo figlio. –

+0

Non aiuta se non riesco a controllare il codice di uscita figlio – tig

-1

Questo non sembra essere una questione di Ruby, ma il vostro sistema operativo, che non è stato specificato. Il raggruppamento dei processi e il routing di sistema di basso livello sono eseguiti dal kernel del sistema operativo.

+0

La differenza è in ruby, confronta il codice sorgente con i collegamenti forniti – tig

+0

Esegui entrambi i comandi in 'strace' e confronta gli output. Forse, 'setpgid' è chiamato in un caso e non nell'altro? – dig