Perl - Gestão de Processos

Você pode usar Perl de várias maneiras para criar novos processos de acordo com seus requisitos. Este tutorial listará alguns métodos importantes e usados ​​com mais frequência para criar e gerenciar processos Perl.

  • Você pode usar variáveis ​​especiais $$ ou $PROCESS_ID para obter o ID do processo atual.

  • Cada processo criado usando qualquer um dos métodos mencionados, mantém seu próprio ambiente virtual dentro %ENV variável.

  • o exit() A função sempre sai apenas do processo filho que executa esta função e o processo principal como um todo não sairá a menos que todos os processos filho em execução tenham saído.

  • Todos os identificadores abertos são dup () - ed em processos-filho, de modo que fechar qualquer identificador em um processo não afeta os outros.

Operador Backstick

A maneira mais simples de executar qualquer comando Unix é usando o operador backstick. Você simplesmente coloca seu comando dentro do operador backstick, o que resultará na execução do comando e retorna seu resultado, que pode ser armazenado da seguinte forma -

#!/usr/bin/perl

@files = `ls -l`;

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

1;

Quando o código acima é executado, ele lista todos os arquivos e diretórios disponíveis no diretório atual -

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

O sistema () Função

Você também pode usar system()função para executar qualquer comando Unix, cuja saída irá para a saída do script perl. Por padrão, é a tela, ou seja, STDOUT, mas você pode redirecioná-lo para qualquer arquivo usando o operador de redirecionamento> -

#!/usr/bin/perl

system( "ls -l")

1;

Quando o código acima é executado, ele lista todos os arquivos e diretórios disponíveis no diretório atual -

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

Tenha cuidado quando seu comando contém variáveis ​​de ambiente de shell como $ PATH ou $ HOME. Tente seguir três cenários -

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

Quando o código acima é executado, ele produz o seguinte resultado dependendo do que está definido na variável 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

A função fork ()

Perl fornece um fork()função que corresponde à chamada de sistema Unix de mesmo nome. Na maioria das plataformas do tipo Unix onde a chamada de sistema fork () está disponível, o fork () do Perl simplesmente a chama. Em algumas plataformas, como Windows, onde a chamada de sistema fork () não está disponível, o Perl pode ser construído para emular fork () no nível do interpretador.

A função fork () é usada para clonar um processo atual. Essa chamada cria um novo processo executando o mesmo programa no mesmo ponto. Ele retorna o pid filho para o processo pai, 0 para o processo filho ou undef se a bifurcação não for bem-sucedida.

Você pode usar exec() dentro de um processo para lançar o executável solicitado, que será executado em uma área de processo separada e exec () irá esperar que ele seja concluído antes de sair com o mesmo status de saída desse processo.

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

Quando o código acima é executado, ele produz o seguinte resultado -

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

o wait() e waitpid()pode ser passado como um ID de pseudo-processo retornado por fork (). Essas chamadas aguardarão adequadamente o término do pseudo-processo e retornarão seu status. Se você bifurca sem nunca esperar seus filhos usandowaitpid()função, você vai acumular zumbis. Em sistemas Unix, você pode evitar isso definindo $ SIG {CHLD} como "IGNORE" da seguinte maneira -

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

Quando o código acima é executado, ele produz o seguinte resultado -

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

A função kill ()

Perl kill('KILL', (Process List)) A função pode ser usada para encerrar um pseudo-processo passando a ele o ID retornado por fork ().

Observe que o uso de kill ('KILL', (Lista de Processos)) em um pseudo-processo () pode normalmente causar vazamentos de memória, porque a thread que implementa o pseudo-processo não tem a chance de limpar seus recursos.

Você pode usar kill() função para enviar qualquer outro sinal para processos alvo, por exemplo, a seguir irá enviar SIGINT para um processo IDs 104 e 102 -

#!/usr/bin/perl

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