2009-04-22 7 views
6

risposte permeabile questa domanda si sono concentrati sulle forcelle:Come posso eliminare le chiamate del sistema Perl quando lo script principale viene ucciso?

Per questa domanda, sto solo chiedendo circa le chiamate alla funzione 'sistema' .

Dire Ho uno script chiamato sleep.pl:

use strict; 
use warnings; 
sleep(300); 

Ho poi ho uno script chiamato kill.pl

use strict; 
use warnings; 
system("sleep.pl"); 

corro kill.pl e l'utilizzo di ps trova il processo id di kill.pl e lo uccide (non usando kill -9, solo normale kill)

sleep.pl è ancora sleepi ng.

Immagino che la soluzione alla mia domanda riguardi un gestore SIG, ma cosa devo mettere nel gestore per uccidere il processo figlio?

+0

Ciò richiede tag aggiuntivi. [uccidere] per esempio. –

risposta

3

Utilizzare setsid per rendere il processo il nuovo capogruppo. Quindi puoi inviare un kill all'ID del gruppo e uccidere tutti i processi che appartengono al gruppo. Tutti i processi generati dal processo leader ereditano l'ID del gruppo e appartengono al gruppo appena creato. Quindi mandare un'uccisione al gruppo li ucciderà tutti. L'unica cosa difficile è che per poter usare setsid è necessario chiudere lo standard in e output, poiché questo è un requisito per setsid.

3
use strict; 
use warnings; 
setpgrp $$, 0; 
system("sleep.pl"); 
END {kill 15, -$$} 

Ma se avete bisogno di questo approccio fate qualcosa di sbagliato. Non dovresti farlo. Esegui e uccidi il processo di uccisione nel modo giusto.

$ perl -e 'system("sleep 100")' & 
[1] 11928 
$ ps f 
    PID TTY  STAT TIME COMMAND 
4564 pts/1 Ss  0:01 /bin/bash 
11928 pts/1 S  0:00 \_ perl -e system("sleep 100") 
11929 pts/1 S  0:00 | \_ sleep 100 
11936 pts/1 R+  0:00 \_ ps f 
$ kill %1 
[1]+ Terminated    perl -e 'system("sleep 100")' 
$ ps f 
    PID TTY  STAT TIME COMMAND 
4564 pts/1 Rs  0:01 /bin/bash 
11949 pts/1 R+  0:00 \_ ps f 

Come funziona? Shell (bash nel mio caso) dovrebbe impostare il processo come leader di gruppo se si esegue sullo sfondo. Quindi se si utilizza la shell di sintassi kill %? nel modo corretto. Confrontare questo:

$ perl -e 'system("sleep 100")' & 
[1] 12109 
$ ps f 
    PID TTY  STAT TIME COMMAND 
4564 pts/1 Rs  0:01 /bin/bash 
12109 pts/1 S  0:00 \_ perl -e system("sleep 100") 
12113 pts/1 S  0:00 | \_ sleep 100 
12114 pts/1 R+  0:00 \_ ps f 
$ kill 12109 
[1]+ Terminated    perl -e 'system("sleep 100")' 
$ ps f 
    PID TTY  STAT TIME COMMAND 
4564 pts/1 Ss  0:01 /bin/bash 
12124 pts/1 R+  0:00 \_ ps f 
12113 pts/1 S  0:00 sleep 100 

Ma kill %? opere in questo modo:

$ perl -e 'system("sleep 100")' & 
[1] 12126 
$ ps f 
    PID TTY  STAT TIME COMMAND 
4564 pts/1 Rs  0:01 /bin/bash 
12126 pts/1 S  0:00 \_ perl -e system("sleep 100") 
12127 pts/1 S  0:00 | \_ sleep 100 
12128 pts/1 R+  0:00 \_ ps f 
$ kill -12126 
[1]+ Terminated    perl -e 'system("sleep 100")' 
$ ps f 
    PID TTY  STAT TIME COMMAND 
4564 pts/1 Ss  0:01 /bin/bash 
12130 pts/1 R+  0:00 \_ ps f 
+0

In sintesi, utilizzare un PID negativo. –

2

la tua domanda è davvero un esempio specifico del più generale "come assicurare un bambino muore quando il genitore muore" questione. Non c'è modo di aggirare questo. Non c'è niente di veramente speciale su system(); si biforca appena un processo figlio e aspetta che esca.

system() è più o meno questo:

sub system 
{ 
    my $kidpid = fork; 
    if ($kidpid) 
    { 
     waitpid $kidpid; 
      # parent process blocks here waiting for the child process to return 
    } 
    else 
    { 
     exec(@_); 
    } 
} 

uccidere il gruppo di processi è di circa l'unica opzione.

Problemi correlati