2014-10-09 4 views
6

ho questo codice di esempio:Perché non è il mio mandato di essere catturato

pid = Process.spawn("exec ruby -e \"trap('TERM'){ puts 'GOT TERM'; sleep 100; }; sleep 100\"") 
Thread.new do 
    Process.wait(pid) 
end 

p `ps aux | grep #{pid} | grep -v grep` 

`kill -TERM #{pid}` 
sleep 1 

p `ps aux | grep #{pid} | grep -v grep` 

Si genera un processo che cattura TERM e quindi invia un termine ad esso.

Il problema è che TERM non viene catturato qui e il processo termina semplicemente.

ruby test.rb 
"sam  8828 0.0 0.0 30576 5052 pts/9 Rl+ 11:48 0:00 ruby -e trap('TERM'){ puts 'GOT TERM'; sleep 100; }; sleep 100\n" 
"" 

Tuttavia ... Se ho appena dormire dopo le uova ed emettere uccidere da un processo diverso il termine viene catturata come previsto.

pid = Process.spawn("exec ruby -e \"trap('TERM'){ puts 'GOT TERM'; sleep 100; }; sleep 100\"") 
Thread.new do 
    Process.wait(pid) 
end 
puts pid 
sleep 100 

Altro guscio

kill -TERM PID 

uscita

GOT TERM 

ulteriormente più, se cerco di allora kill il processo dal processo di origine dopo la sua intrappolato nel termine gestore non sarà più ucciderà esso.

Che cosa sta succedendo qui, perché TERM non viene recapitato correttamente al processo figlio dal genitore?

+0

interessante ... quale sistema operativo stai? per me funziona correttamente (MacOS): '" 71794 0.0 0.1 2443544 2932 s001 R + 9:22 PM 0: 00.01 ruby ​​-e trap ('TERM') {puts 'GOT TERM'; sleep 100;}; sleep 100 \ n" GOT TERM " 71.794 0,6 0,2 2.471.356 8168 S001 S + 9:22 0: 00.05 rubino trappola -e ('term') {puts 'Si TERM'; dormire 100;}; dormire 100 \ n" ' – moonfly

+0

su Linux ... In realtà sospetto che questo sia specifico di Linux e correlato al modo in cui" exec "opera, un secondo pid è coinvolto –

+0

Sembra che ci siano molti PID coinvolti. Stavo indagando sul comportamento tramite strace e ho trovato che per un'invocazione del tuo script sono stati creati un totale di 14 (1) file di traccia PID. – orangejulius

risposta

11

Ahh, ho capito,

TERM è stato inviato al processo troppo presto, prima che l'interprete Ruby fosse in grado di stabilire il gancio. Quindi lo termina.

a sleep 1 prima del kill -TERM #{pid} ordina il problema.

+1

Trivial in the retrospettiva, infatti. :) 'Thread.pass' può funzionare anche al posto di' sleep', ma di nuovo potrebbe dipendere dal sistema. – moonfly

+0

cosa intendi con "stabilire il gancio"? se Process.spawn è ritornato con un pid, il processo non dovrebbe essere immediatamente ricettivo ai segnali? –

+0

ohhh l'interprete ruby ​​invocato all'interno del processo non ha ancora fatto lo spooling ... gotcha. –