2012-04-18 18 views
8

sto imparando la programmazione di sistemi attraverso rubino e sto avendo difficoltà a capire questo comportamento:Hai bisogno di aiuto comprensione del rubino Process.detach

pid = fork do 
    Signal.trap("USR1") do 
    puts "hello!" 
    end 
    Signal.trap("TERM") do 
    puts "Terminating" 
    exit 
    end 
    loop do 
    end 
end 

Process.detach(pid) 

Process.kill("USR1", pid) 
Process.kill("USR1", pid) 
Process.kill("USR1", pid) 
Process.kill("USR1", pid) 

Process.kill("TERM", pid) 

Questo uscite come mi aspetto:

hello! 
hello! 
hello! 
hello! 
Terminating 

Tuttavia, se io commento Process.detach, il processo figlio sembra rispondere solo al segnale una volta (e dopo il termine?):

Terminating 
hello! 

Sono confuso sul motivo per cui ciò accade quando non scollego il processo, anche se l'ho inviato USR1 quattro volte. Qualcuno può aiutare a spiegare questo comportamento? Penso di non capire cosa significhi staccare un processo.

Grazie mille!

risposta

7

È tutto a posto, temo, la differenza è dovuta al modo in cui le istruzioni del processo principale e del processo biforcato sono pianificate l'una rispetto all'altra.

Quando si esegue Process.detach, viene creato un nuovo thread che attende il risultato di uscita del processo specificato. È possibile sostituire Process.detach con

Thread.new { Process.wait(pid) } 

e ottenere lo stesso effetto. Sospetto che la chiamata a staccare (e generare un nuovo thread) dia al tuo processo biforcuto, come effetto collaterale, la possibilità di essere programmato.

Se non si dispone di un distacco, suppongo che il processo biforcato non abbia la possibilità di essere eseguito nel momento in cui gli si dice di morire.

È possibile vedere cosa intendo per tempistica relativa inserendo alcune chiamate di sospensione nel codice per vedere se è possibile ottenere lo stesso comportamento osservato senza distacco.

Ad esempio, questo sembra funzionare per me, anche se la vostra situazione potrebbe essere diversa a seconda della piattaforma host:

pid = fork do 
    Signal.trap("USR1") do 
    puts "hello!" 
    end 
    Signal.trap("TERM") do 
    puts "Terminating" 
    exit 
    end 
    loop do 
    end 
end 

sleep(1) 

Process.kill("USR1", pid) 
Process.kill("USR1", pid) 
Process.kill("USR1", pid) 
Process.kill("USR1", pid) 

sleep(1) 

Process.kill("TERM", pid) 

Questo produce:

hello! 
hello! 
hello! 
hello! 
Terminating 
+0

ah, grazie! Sì, immagino che la programmazione sia ciò che mi confonde (sono su OSX, dovrei provarlo su una scatola virtuale e vedere cosa succede). – ambertch

Problemi correlati