perlfork - Online na nuvem

Este é o comando perlfork que pode ser executado no provedor de hospedagem gratuita OnWorks usando uma de nossas várias estações de trabalho online gratuitas, como Ubuntu Online, Fedora Online, emulador Windows online ou emulador MAC OS online

PROGRAMA:

NOME


perlfork - emulação fork () do Perl

SINOPSE


NOTA: A partir da versão 5.8.0, a emulação fork () foi consideravelmente
amadurecido. No entanto, ainda existem alguns bugs e diferenças conhecidos
de real fork () que pode afetar você. Veja os "BUGS" e
Seções "CAVEATS AND LIMITATIONS" abaixo.

Perl fornece um garfo() palavra-chave que corresponde à chamada de sistema Unix de mesmo nome.
Na maioria das plataformas do tipo Unix, onde o garfo() chamada de sistema está disponível, Perl's garfo()
simplesmente chama isso.

Em algumas plataformas, como o Windows, onde o garfo() chamada de sistema não está disponível, Perl pode
ser construído para emular garfo() ao nível do intérprete. Embora a emulação seja projetada para
ser o mais compatível possível com o real garfo() no nível do programa Perl, há
existem certas diferenças importantes que decorrem do fato de que toda a pseudo criança
"processos" criados desta forma vivem no mesmo processo real, tanto quanto o sistema operacional
está preocupado.

Este documento fornece uma visão geral das capacidades e limitações do
garfo() emulação. Observe que os problemas discutidos aqui não se aplicam a plataformas
onde um real garfo() está disponível e o Perl foi configurado para usá-lo.

DESCRIÇÃO


O garfo() a emulação é implementada no nível do interpretador Perl. O que isto significa
em geral é correr garfo() irá realmente clonar o interpretador em execução e todos os seus
state e execute o interpretador clonado em um thread separado, iniciando a execução no novo
fio logo após o ponto onde o garfo() foi chamado no pai. Vamos nos referir a
o thread que implementa esse "processo" filho como o pseudo-processo.

Para o programa Perl que chamou garfo(), tudo isso é projetado para ser transparente. O
pai retorna do garfo() com um ID de pseudo-processo que pode ser usado posteriormente em
quaisquer funções de manipulação de processos; a criança retorna do garfo() com um valor de 0 a
significa que é o pseudo-processo filho.

Comportamento of de outros Perl características in "fork" pseudoprocessos
A maioria dos recursos do Perl se comporta de maneira natural nos pseudo-processos.

$$ ou $PROCESS_ID
Esta variável especial está configurada corretamente para o ID do pseudo-processo. Isso pode ser usado
para identificar pseudo-processos dentro de uma sessão particular. Observe que este valor é
sujeito a reciclagem se algum pseudo-processo for iniciado após outros terem sido
esperar()-ed em.

%ENV Cada pseudoprocesso mantém seu próprio ambiente virtual. Modificações em %ENV
afetam o ambiente virtual e são visíveis apenas dentro desse pseudoprocesso,
e em quaisquer processos (ou pseudoprocessos) iniciados a partir dele.

chdir () e todos os outros embutidos que aceitam nomes de arquivos
Cada pseudo-processo mantém sua própria ideia virtual do diretório atual.
Modificações no diretório atual usando chdir () são apenas visíveis dentro disso
pseudo-processo e em quaisquer processos (ou pseudo-processos) iniciados a partir dele. Tudo
acessos de arquivo e diretório do pseudo-processo mapearão corretamente o virtual
diretório de trabalho para o diretório de trabalho real apropriadamente.

esperar() e waitpid ()
esperar() e waitpid () pode ser passado um ID de pseudo-processo retornado por garfo(). Estes
as chamadas irão esperar corretamente pelo término do pseudo-processo e retornar seu
estado.

matar() "kill('KILL', ...)" pode ser usado para encerrar um pseudo-processo passando-lhe o ID
devolvido por garfo(). O resultado da eliminação em um pseudo-processo é imprevisível e
não deve ser usado, exceto em circunstâncias extremas, porque o funcionamento
sistema pode não garantir a integridade dos recursos do processo quando um thread em execução
Está terminado. O processo que implementa os pseudo-processos pode ser bloqueado
e o interpretador Perl trava. Observe que usar "kill('KILL', ...)" em um
pseudo-processo() pode normalmente causar vazamentos de memória, porque o segmento que
implementa o pseudoprocesso não tem a chance de limpar seus recursos.

"kill ('TERM', ...)" também pode ser usado em pseudo-processos, mas o sinal não
ser entregue enquanto o pseudo-processo é bloqueado por uma chamada de sistema, por exemplo, em espera
para um soquete conectar, ou tentando ler de um soquete sem dados disponíveis.
A partir do Perl 5.14, o processo pai não vai esperar que os filhos saiam uma vez
eles foram sinalizados com "kill ('TERM', ...)" para evitar deadlock durante o processo
saída. Você terá que chamar explicitamente waitpid () para garantir que a criança tenha tempo
para se limpar, mas você também é responsável pelo fato de a criança não ser
bloqueando no I / O também.

exec () chamada exec () dentro de um pseudo-processo realmente gera o executável solicitado em
um processo separado e espera que ele seja concluído antes de sair com a mesma saída
status como esse processo. Isso significa que o ID do processo relatado no
o executável em execução será diferente do que o Perl anterior garfo() pode ter
devolvida. Da mesma forma, quaisquer funções de manipulação de processo aplicadas ao ID
devolvido por garfo() afetará o pseudo-processo de espera que chamou exec (), não
o processo real que está esperando após o exec ().

Quando exec () é chamado dentro de um pseudo-processo, em seguida, métodos DESTROY e blocos END
ainda será chamado após o retorno do processo externo.

Saída() Saída() sempre sai apenas do pseudo-processo em execução, após automaticamente
esperar()-ing para quaisquer pseudo-processos filho pendentes. Observe que isso significa que
o processo como um todo não sairá a menos que todos os pseudo-processos em execução tenham
saiu. Veja abaixo algumas limitações com manipuladores de arquivos abertos.

Abrir identificadores para arquivos, diretórios e sockets de rede
Todas as alças abertas são dup ()-ed em pseudo-processos, de modo que fechar qualquer handle em
um processo não afeta os outros. Veja abaixo algumas limitações.

Recursos limites
Aos olhos do sistema operacional, pseudo-processos criados por meio do garfo() emulação são
simplesmente threads no mesmo processo. Isso significa que quaisquer limites de nível de processo impostos por
o sistema operacional se aplica a todos os pseudo-processos considerados juntos. Isso inclui qualquer
limites impostos pelo sistema operacional sobre o número de arquivos abertos, diretórios e soquetes
manipula, limites de uso de espaço em disco, limites de tamanho de memória, limites de utilização de CPU, etc.

Matança da principal processo
Se o processo pai for morto (usando o Perl matar() embutido, ou usando algum
meios externos) todos os pseudo-processos são eliminados também, e todo o processo sai.

Lifetime of da principal processo e pseudoprocessos
Durante o curso normal dos eventos, o processo pai e todos os pseudo-processos iniciados por
ele esperará que seus respectivos pseudo-filhos sejam concluídos antes de sair. Isto
significa que o pai e cada pseudo-filho criado por ele que também é um pseudo-pai
só sairão depois que seus pseudo-filhos tiverem saído.

A partir do Perl 5.14, um pai não esperar() automaticamente para qualquer criança que foi
sinalizado com "kill ('TERM', ...)" para evitar um deadlock caso a criança esteja bloqueando
I / O e nunca recebe o sinal.

RESSALVAS E LIMITAÇÕES


BEGIN blocos
O garfo() a emulação não funcionará totalmente corretamente quando chamada de dentro de um
Bloco BEGIN. A cópia bifurcada executará o conteúdo do bloco BEGIN, mas irá
não continue analisando o fluxo de origem após o bloco BEGIN. Por exemplo,
considere o seguinte código:

INÍCIO {
bifurcação e saída; # fork filho e sai do pai
imprimir "interno \ n";
}
imprimir "externo \ n";

Isso irá imprimir:

interior

ao invés do esperado:

interior
exterior

Esta limitação surge de dificuldades técnicas fundamentais na clonagem e
reiniciar as pilhas usadas pelo analisador Perl no meio de uma análise.

Abrir filehandles
Quaisquer manipuladores de arquivos abertos no momento do garfo() será dup ()-ed. Assim, os arquivos
pode ser fechado independentemente no pai e no filho, mas tome cuidado para que o dup ()-ed
handles ainda compartilharão o mesmo ponteiro de busca. Alterando a posição de busca no
o pai vai mudá-lo no filho e vice-versa. Pode-se evitar isso abrindo
arquivos que precisam de ponteiros de busca distintos separadamente no filho.

Em alguns sistemas operacionais, notavelmente Solaris e Unixware, chamando "exit ()" de um
o processo filho irá liberar e fechar os manipuladores de arquivos abertos no pai, assim
corrompendo os manipuladores de arquivos. Nestes sistemas, é sugerido chamar "_exit ()"
em vez de. "_exit ()" está disponível em Perl através do módulo "POSIX". Por favor
consulte as páginas de manual do seu sistema para obter mais informações sobre isso.

Abrir identificadores de diretório
O Perl irá ler completamente de todos os identificadores de diretório aberto até chegarem ao fim
do riacho. Será então searchdir () de volta ao local original e tudo
futuro readdir () solicitações serão atendidas a partir do buffer de cache. Que significa
que nem o identificador de diretório mantido pelo processo pai, nem aquele mantido por
o processo filho verá todas as alterações feitas no diretório após o garfo()
ligar.

Observe que rewinddir () tem uma limitação semelhante no Windows e não forçará
readdir () para ler o diretório novamente. Apenas um diretório recém-aberto
o identificador refletirá as mudanças no diretório.

Tubo bifurcado abrir() Ainda não implementado
As construções "open (FOO," | - ")" e "open (BAR," - | ")" ainda não foram implementadas.
Essa limitação pode ser facilmente contornada em um novo código, criando um tubo
explicitamente. O exemplo a seguir mostra como escrever para uma criança bifurcada:

# simular aberto (FOO, "| -")
subpipe_to_fork ($) {
meu $ parent = shift;
pipe my $ child, $ parent or die;
meu $ pid = fork ();
die "fork () falhou: $!" a menos que definido $ pid;
if ($ pid) {
fechar $ child;
}
else {
fechar $ parent;
abrir (STDIN, "<& =". fileno ($ child)) ou morrer;
}
$ pid;
}

if (pipe_to_fork ('FOO')) {
# pai
print FOO "pipe_to_fork\n";
fechar FOO;
}
else {
# filho
enquanto ( ) { imprimir; }
saída(0);
}

E este aqui lê da criança:

# simular aberto (FOO, "- |")
subpipe_from_fork ($) {
meu $ parent = shift;
canalizar $ pai, meu $ filho ou morrer;
meu $ pid = fork ();
die "fork () falhou: $!" a menos que definido $ pid;
if ($ pid) {
fechar $ child;
}
else {
fechar $ parent;
abrir (STDOUT, "> & =". fileno ($ child)) ou morrer;
}
$ pid;
}

if (pipe_from_fork('BAR')) {
# pai
enquanto ( ) { imprimir; }
fechar BAR;
}
else {
# filho
print "pipe_from_fork\n";
saída(0);
}

Tubo bifurcado abrir() construções serão suportadas no futuro.

Estado global mantido por XSUBs
Sub-rotinas externas (XSUBs) que mantêm seu próprio estado global podem não funcionar
corretamente. Esses XSUBs precisarão manter bloqueios para proteger
acesso a dados globais de diferentes pseudoprocessos, ou manter todo o seu estado
na tabela de símbolos Perl, que é copiada naturalmente quando garfo() é chamado. UMA
mecanismo de retorno de chamada que fornece extensões uma oportunidade de clonar seu estado
será fornecido em um futuro próximo.

Intérprete embutido em um aplicativo maior
O garfo() a emulação pode não se comportar conforme o esperado quando é executada em um
aplicativo que incorpora um interpretador Perl e chama APIs Perl que podem avaliar
bits de código Perl. Isso decorre do fato de que a emulação só possui conhecimento
sobre as próprias estruturas de dados do interpretador Perl e não sabe nada sobre o
contendo o estado do aplicativo. Por exemplo, qualquer estado realizado no
a pilha de chamadas do próprio aplicativo está fora de alcance.

Segurança da linha de extensões
Uma vez que o garfo() emulação executa código em vários threads, extensões chamando em
bibliotecas não thread-safe podem não funcionar de forma confiável ao chamar garfo(). Como Perl's
suporte de threading torna-se gradualmente mais amplamente adotado, mesmo em plataformas com um
nativo garfo(), espera-se que tais extensões sejam corrigidas para segurança de thread.

PORTABILIDADE RESSALVAS


No código Perl portátil, "kill (9, $ child)" não deve ser usado em processos bifurcados. Matando um
o processo bifurcado não é seguro e tem resultados imprevisíveis. Ver "matar()", acima.

Use o perlfork online usando os serviços onworks.net



Programas online mais recentes para Linux e Windows