2010-01-25 13 views

Respuesta

17

De respuesta perlfaq8 's a How do I start a process in the background?


Varios módulos pueden iniciar otros procesos que no bloquean su programa Perl . Puede utilizar IPC :: Open3, Parallel :: Jobs, IPC :: Run y ​​algunos de los módulos POE. Ver CPAN para más detalles.

También es posible usar

system("cmd &") 

o puede utilizar tenedor como se documenta en "tenedor" en perlfunc, con más ejemplos en perlipc. Algunas cosas a tener en cuenta, si estás en un Unix como sistema de :

stdin, stdout y stderr son compartidos

Tanto el proceso principal y la backgrounded (el "niño" proceso) comparten los mismos manejadores de archivo STDIN, STDOUT y STDERR. Si ambos intentan acceder a ellos de una vez, pueden suceder cosas extrañas. Usted puede querer cerrar o volver a abrir estos para el niño. Puede obtener alrededor de esto con "abrir" una tubería (ver "abrir" en perlfunc) pero en algunos sistemas significa que el proceso hijo no puede sobrevivir al padre .

señales

Vas a tener que coger la señal SIGCHLD, y posiblemente SIGPIPE también. SIGCHLD se envía cuando finaliza el proceso de fondo. SIGPIPE es enviado cuando escribe en un identificador de archivo cuyo proceso hijo ha cerrado (un SIGPIPE no capturado puede hacer que su programa muera en silencio). Esto no es un problema con "system (" cmd & ")".

Zombies

Usted tiene que estar preparado para "cosechar" el proceso hijo cuando acabados.

$SIG{CHLD} = sub { wait }; 

    $SIG{CHLD} = 'IGNORE'; 

También puede usar una horquilla doble. Inmediatamente esperas() para tu primer hijo , y el daemon init esperará() para tu nieto una vez que salga.

unless ($pid = fork) { 
     unless (fork) { 
      exec "what you really wanna do"; 
      die "exec failed!"; 
     } 
     exit 0; 
    } 
    waitpid($pid, 0); 

Ver "Señales" en perlipc para otros ejemplos de código para hacer esto. Los zombis no son un problema con "system (" prog & ")".

+0

Muchas gracias, no había pensado utilizar el operador de shell de fondo en el comando. Eso hizo el truco. Desafortunadamente no puedo usar los demás porque estoy trabajando en un sistema severamente limitado con casi ningún módulo. –

+0

Ah, sí, si emite un comando system() con '&' char, vuelve enseguida, por lo que el método del operador back-tick que había sugerido no era tan bueno; mejor usar la llamada al sistema de Perl en lugar de llamar a un todo nueva copia del caparazón. –

1

Si quiere demonizar su script Perl que había mirar en Proc::Daemon.

+0

En realidad, no quiero demonizarlo, solo tengo que ejecutar un script de vigilancia en el fondo mientras dure la ejecución de mi script principal. Y solo tengo Perl 5.6.0 básico para trabajar, porque esto se está ejecutando en un sistema integrado con una memoria muy limitada y prácticamente no tengo módulos con los que trabajar. –

0

bien no se debe utilizar como system() entiendo esta llamada esperará a que el retorno de la función antes de continuar con la ejecución. Simplemente me limitaría a linux e iniciaría el proceso de esa manera, aunque tenga en cuenta que de esta manera se enviará una nueva copia del intérprete de comandos y, por lo tanto, si está buscando rendimiento, no lo haría en un ciclo:

process_name > /dev/null 2>&1 &;

que se iniciará el proceso de reorientación y STDOUTSTDERR-/dev/null.

0

Si desea que el proceso "secundario" del perro guardián desaparezca cuando finaliza el proceso "principal", no desea realmente que el proceso principal "active y olvide" el proceso hijo. O bien debe bifurcar (como lo describe el brian d foy) o pasar el PID del padre al hijo (para que este último pueda sondear la tabla de proceso, no recomendado).

+0

En realidad, ejecutar una secuencia de comandos de vigilancia como un proceso secundario probablemente sea una mala idea ya que se supone que el perro guardián debe hacer algo si la secuencia de comandos principal muere inesperadamente (pero si el padre muere también lo hacen todos sus hijos). Otra forma de hacerlo es hacer que el "proceso principal" configure un conducto con nombre y escribir mensajes de "latido" + un mensaje de "finalización" al salir, mientras que el perro guardián (lanzado en modo verdadero "disparar y olvidarse" system ("cmd &")) lee desde la tubería con nombre y avisos cuando llega el mensaje "listo" o dejan de aparecer los mensajes de "latido". – Peter

Cuestiones relacionadas