Perl - Gestion des processus

Vous pouvez utiliser Perl de différentes manières pour créer de nouveaux processus selon vos besoins. Ce tutoriel répertorie quelques méthodes importantes et les plus fréquemment utilisées pour créer et gérer des processus Perl.

  • Vous pouvez utiliser des variables spéciales $$ ou $PROCESS_ID pour obtenir l'ID de processus actuel.

  • Chaque processus créé en utilisant l'une des méthodes mentionnées, maintient son propre environnement virtuel avec-in %ENV variable.

  • le exit() La fonction quitte toujours uniquement le processus enfant qui exécute cette fonction et le processus principal dans son ensemble ne se terminera que si tous les processus enfants en cours d'exécution sont sortis.

  • Toutes les poignées ouvertes sont dup () - éditées dans les processus enfants, de sorte que la fermeture des poignées dans un processus n'affecte pas les autres.

Opérateur Backstick

Cette manière la plus simple d'exécuter toute commande Unix consiste à utiliser l'opérateur backstick. Vous mettez simplement votre commande à l'intérieur de l'opérateur backstick, ce qui entraînera l'exécution de la commande et retournera son résultat qui peut être stocké comme suit -

#!/usr/bin/perl

@files = `ls -l`;

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

1;

Lorsque le code ci-dessus est exécuté, il répertorie tous les fichiers et répertoires disponibles dans le répertoire courant -

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 fonction system ()

Vous pouvez aussi utiliser system()pour exécuter toute commande Unix, dont la sortie ira à la sortie du script perl. Par défaut, c'est l'écran, c'est-à-dire STDOUT, mais vous pouvez le rediriger vers n'importe quel fichier en utilisant l'opérateur de redirection> -

#!/usr/bin/perl

system( "ls -l")

1;

Lorsque le code ci-dessus est exécuté, il répertorie tous les fichiers et répertoires disponibles dans le répertoire courant -

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

Soyez prudent lorsque votre commande contient des variables d'environnement shell comme $ PATH ou $ HOME. Essayez de suivre trois scénarios -

#!/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;

Lorsque le code ci-dessus est exécuté, il produit le résultat suivant en fonction de ce qui est défini dans la variable 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 fonction fork ()

Perl fournit un fork()fonction qui correspond à l'appel système Unix du même nom. Sur la plupart des plates-formes de type Unix où l'appel système fork () est disponible, fork () de Perl l'appelle simplement. Sur certaines plates-formes telles que Windows où l'appel système fork () n'est pas disponible, Perl peut être construit pour émuler fork () au niveau de l'interpréteur.

La fonction fork () est utilisée pour cloner un processus en cours. Cet appel crée un nouveau processus exécutant le même programme au même point. Il renvoie le pid enfant au processus parent, 0 au processus enfant ou undef si la fourche échoue.

Vous pouvez utiliser exec() dans un processus pour lancer l'exécutable demandé, qui sera exécuté dans une zone de processus séparée et exec () attendra qu'il se termine avant de quitter avec le même statut de sortie que ce processus.

#!/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;

Lorsque le code ci-dessus est exécuté, il produit le résultat suivant -

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

le wait() et waitpid()peut être passé en tant qu'ID de pseudo-processus renvoyé par fork (). Ces appels attendront correctement la fin du pseudo-processus et renverront son état. Si vous fourchez sans jamais attendre vos enfantswaitpid()fonction, vous accumulerez des zombies. Sur les systèmes Unix, vous pouvez éviter cela en définissant $ SIG {CHLD} sur "IGNORE" comme suit -

#!/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;

Lorsque le code ci-dessus est exécuté, il produit le résultat suivant -

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

La fonction kill ()

Perl kill('KILL', (Process List)) La fonction peut être utilisée pour terminer un pseudo-processus en lui passant l'ID renvoyé par fork ().

Notez que l'utilisation de kill ('KILL', (Process List)) sur un pseudo-processus () peut généralement provoquer des fuites de mémoire, car le thread qui implémente le pseudo-processus n'a pas la possibilité de nettoyer ses ressources.

Vous pouvez utiliser kill() fonction pour envoyer tout autre signal aux processus cibles, par exemple suivant enverra SIGINT à un processus ID 104 et 102 -

#!/usr/bin/perl

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