Perl - Gestión de procesos

Puede utilizar Perl de varias formas para crear nuevos procesos según sus requisitos. Este tutorial enumerará algunos métodos importantes y de uso más frecuente para crear y administrar procesos Perl.

  • Puedes usar variables especiales $$ o $PROCESS_ID para obtener la identificación del proceso actual.

  • Cada proceso creado utilizando cualquiera de los métodos mencionados, mantiene su propio entorno virtual dentro de %ENV variable.

  • los exit() function siempre sale solo del proceso hijo que ejecuta esta función y el proceso principal como un todo no saldrá a menos que todos los procesos hijo en ejecución hayan salido.

  • Todos los identificadores abiertos son dup () - ed en procesos secundarios, de modo que cerrar cualquier identificador en un proceso no afecta a los demás.

Operador de backstick

Esta forma más sencilla de ejecutar cualquier comando de Unix es mediante el operador de retroceso. Simplemente coloque su comando dentro del operador de retroceso, lo que dará como resultado la ejecución del comando y devuelve su resultado, que se puede almacenar de la siguiente manera:

#!/usr/bin/perl

@files = `ls -l`;

foreach $file (@files) {
   print $file;
}

1;

Cuando se ejecuta el código anterior, enumera todos los archivos y directorios disponibles en el directorio actual:

drwxr-xr-x 3 root root 4096 Sep 14 06:46 9-14
drwxr-xr-x 4 root root 4096 Sep 13 07:54 android
-rw-r--r-- 1 root root  574 Sep 17 15:16 index.htm
drwxr-xr-x 3  544  401 4096 Jul  6 16:49 MIME-Lite-3.01
-rw-r--r-- 1 root root   71 Sep 17 15:16 test.pl
drwx------ 2 root root 4096 Sep 17 15:11 vAtrJdy

La función system ()

También puedes usar system()función para ejecutar cualquier comando de Unix, cuya salida irá a la salida del script perl. De forma predeterminada, es la pantalla, es decir, STDOUT, pero puede redirigirla a cualquier archivo utilizando el operador de redirección> -

#!/usr/bin/perl

system( "ls -l")

1;

Cuando se ejecuta el código anterior, enumera todos los archivos y directorios disponibles en el directorio actual:

drwxr-xr-x 3 root root 4096 Sep 14 06:46 9-14
drwxr-xr-x 4 root root 4096 Sep 13 07:54 android
-rw-r--r-- 1 root root  574 Sep 17 15:16 index.htm
drwxr-xr-x 3  544  401 4096 Jul  6 16:49 MIME-Lite-3.01
-rw-r--r-- 1 root root   71 Sep 17 15:16 test.pl
drwx------ 2 root root 4096 Sep 17 15:11 vAtrJdy

Tenga cuidado cuando su comando contenga variables ambientales de shell como $ PATH o $ HOME. Intente seguir tres escenarios:

#!/usr/bin/perl

$PATH = "I am Perl Variable";

system('echo $PATH');  # Treats $PATH as shell variable
system("echo $PATH");  # Treats $PATH as Perl variable
system("echo \$PATH"); # Escaping $ works.

1;

Cuando se ejecuta el código anterior, produce el siguiente resultado dependiendo de lo que se establezca en la variable de shell $ PATH.

/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin
I am Perl Variable
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin

La función fork ()

Perl proporciona una fork()función que corresponde a la llamada al sistema Unix del mismo nombre. En la mayoría de las plataformas similares a Unix donde la llamada al sistema fork () está disponible, fork () de Perl simplemente la llama. En algunas plataformas, como Windows, donde la llamada al sistema fork () no está disponible, Perl se puede construir para emular fork () a nivel de intérprete.

La función fork () se usa para clonar un proceso actual. Esta llamada crea un nuevo proceso que ejecuta el mismo programa en el mismo punto. Devuelve el pid secundario al proceso principal, 0 al proceso secundario o undef si la bifurcación no tiene éxito.

Puedes usar exec() función dentro de un proceso para iniciar el ejecutable solicitado, que se ejecutará en un área de proceso separada y exec () esperará a que se complete antes de salir con el mismo estado de salida que ese proceso.

#!/usr/bin/perl

if(!defined($pid = fork())) {
   # fork returned undef, so unsuccessful
   die "Cannot fork a child: $!";
} elsif ($pid == 0) {
   print "Printed by child process\n";
   exec("date") || die "can't exec date: $!";
  
} else {
   # fork returned 0 nor undef
   # so this branch is parent
   print "Printed by parent process\n";
   $ret = waitpid($pid, 0);
   print "Completed process id: $ret\n";

}

1;

Cuando se ejecuta el código anterior, produce el siguiente resultado:

Printed by parent process
Printed by child process
Tue Sep 17 15:41:08 CDT 2013
Completed process id: 17777

los wait() y waitpid()se puede pasar como un ID de pseudoproceso devuelto por fork (). Estas llamadas esperarán adecuadamente la terminación del pseudoproceso y devolverán su estado. Si bifurca sin esperar a que sus hijos usenwaitpid()función, acumularás zombies. En sistemas Unix, puede evitar esto configurando $ SIG {CHLD} en "IGNORAR" de la siguiente manera:

#!/usr/bin/perl

local $SIG{CHLD} = "IGNORE";
 
if(!defined($pid = fork())) {
   # fork returned undef, so unsuccessful
   die "Cannot fork a child: $!";
} elsif ($pid == 0) {
   print "Printed by child process\n";
   exec("date") || die "can't exec date: $!";
  
} else {
   # fork returned 0 nor undef
   # so this branch is parent
   print "Printed by parent process\n";
   $ret = waitpid($pid, 0);
   print "Completed process id: $ret\n";

}

1;

Cuando se ejecuta el código anterior, produce el siguiente resultado:

Printed by parent process
Printed by child process
Tue Sep 17 15:44:07 CDT 2013
Completed process id: -1

La función kill ()

Perl kill('KILL', (Process List)) La función se puede usar para terminar un pseudoproceso pasándole el ID devuelto por fork ().

Tenga en cuenta que el uso de kill ('KILL', (Lista de procesos)) en un pseudoproceso () normalmente puede causar pérdidas de memoria, porque el hilo que implementa el pseudoproceso no tiene la oportunidad de limpiar sus recursos.

Puedes usar kill() función para enviar cualquier otra señal a los procesos de destino, por ejemplo, lo siguiente enviará SIGINT a los ID de proceso 104 y 102 -

#!/usr/bin/perl

kill('INT', 104, 102);
 
1;