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;