[Cascavel-pm] Res: Problema com pipe

Gabriel Sancinetti gabrielssan em yahoo.com
Quinta Fevereiro 18 08:45:48 PST 2010


Para aqueles que tiverem dúvidas, segue pagina de onde retirei a estrutura do código.

http://www.wellho.net/solutions/perl-controlling-multiple-asyncronous-processes-in-perl.html





________________________________
De: Daniel de Oliveira Mantovani <daniel.oliveira.mantovani em gmail.com>
Para: Cascavel Perl Mongers <cascavel-pm em pm.org>
Enviadas: Quinta-feira, 18 de Fevereiro de 2010 13:11:16
Assunto: Re: [Cascavel-pm] Problema com pipe

Você acha mesmo que executar 80 comandos de uma vez e elevar o load da
máquina ao infinito e além vai resolver o problema ?

Me parece que o problema é muito além de um script ou dois. Uma hora
esse "treco" vai parar, se já é que não para. Agora é a hora de
"sentar, pensar e refazer"

Da uma lida em: perldoc perlipc vai te ajudar nesse seu "treco".

2010/2/18 Gabriel Sancinetti <gabrielssan em yahoo.com>:
> Olá,
>
> Estou trabalhando com perl há alguns meses e recentemente me deparei com um
> grande desafio.(pelo menos para mim).
> Não sei se esta lista é a adequada, mas ja gastei 4 semanas pesquisando no
> google e nada de solução.
>
> Enfim...
> Preciso reduzir o tempo de execução de um script de aproximadamente 50
> minutos para 8 minutos.
> 1 - Este scrip faz mais de 2 mil "chamadas externas" de sistema operacional
> ( `comando` ) com timeout de 5 a 10 seguntos.
> 2 - É necessário processar o STDOUT e EXIT STATUS do comando em um processo
> único não necessáriamente em sequencia.
>
> A solução com certeza deve implementar alguma forma de paralelismo.
> Não consegui desenvolver uma forma de utilizar "open" no script. Então perdi
> para uma solução de baixo nível.
>
> Encontrei uma solução que quase atendeu minhas expectativas, mas estou com
> problemas de nível de Sistema Operacional nela.
>
> Recomendo que deem uma olhada no código pois agora irei descrever o problema
> deste código.
>
> O meu problema é a ocorrencia de grande quantidade de TIMEOUTs, isto é, o
> processo pai não recebe/processa as respostas dos filhos.
> Separei as chamadas de sistema em grupos de 80 comandos.
> Quando executo o script sem o sleep tanto no processo pai quanto no processo
> filho chego q ter mais de 50% de perda de respostas, (TIMEOUT)
> Conforme adiciono tempo ao sleep no processo filho, consigo reduzir a
> quantidade de TIMEOUTS considerávelmente, mas longe do satizfatório.
> Já quando adiciono o sleep antes do fork do processo filho a ocorrencia de
> TIMEOUTs cai a menos de 0.5%, mas o tempo de execução do script se aproxima
> do original (40 minutos).
>
> Acredito que meu problema esteja no processamento do sinal (kill), mas
> também pode ser no pipe. Não acredito que seja no pipe pois não ocorre erros
> no syswrite e no sysread, etc.
> Já estou quase certo de que terei que refazer tudo de outro jeito, mas estou
> sem idéias e preciso da opinião de pessoas mais experientes.
>
> Então, agradeço desde já a atenção de vocês e espero susgestões para
> corrigir este script ou para refazer de outro jeito.
>
> Cordialmente,
>
> Gabriel
>
> ps: Ignorem erros de sintaxe e identação pois editei o codigo no corpo da
> mensagem.
>
> #########################################################################################################
> my $gotone;
> sub doneit {
>     $gotone=$gotone+1;
> #    logMsg("Got one! ($gotone)");
> }
>
> $SIG{USR1} = \&doneit;
> my $parent = $$;
> $kids=0;
> $gotone=0;
>
> #Para não sobrecarregar o servidor, a lista de comandos é dividida em grupos
> de 80. (@CHECKS = (cmd1 .. cmd80))
> foreach my $checkID (@CHECKS) {
>
>             pipe *{$checkID},PIPEN;
>
>              #Espera do processo pai antes de cada fork para testes
>             # Este tempo de espera é diferencial na ocorrencia da falha
> #           sleep(10);
>
>             $PIDs{$checkID} = fork();
>             if (not defined $PIDs{$checkID}) {
>                 logMsg("ERROR: Fork FAILURE!!!");
>
>             } elsif ($PIDs{$checkID} == 0) {
>                 # Processo filho executa espera diminuindo probalidade de
> sobrecarga de respostas para processo pai.
>                 my $random_number = rand();
> #                my $random_wait = $random_number*3;
>                 sleep($random_wait);
>
>                 my $saida;
>                 $saida = `cmdN`;
>                 my $exit_value = $? >> 8;
>
>                 #Escreve saida no pipe para processo pai.
>                 my $write = syswrite PIPEN, "$exit_value;$saida";
>                 if (!defined($write)) {
>                     logMsg("ERROR (write pipe): $!");
>                 }
>
>                 close *{$checkID};
>                 kill "USR1",$parent;
>                 exit();
>                 # fim do processo filho
>             } else {
>                 # Contagem de número de processos filhos no pai (80)
>                 $kids++;
>             }
>         }
>
>         # While para processamento de respostas dos processos filhos
>         # deve ser garantido que todos filhos serão processados
>         while ($kids > 0) {
>
>             # Aguarda 10 segundos depois de receber ultimo sinal (USR1).
> $gotone é uma variavel global que contabiliza o numero de processos filhos
> que ja responderam. Esta variavel é decrementada de acordo com o
> processamento dos filhos para controle de TIMEOUT.
>             my $timeout = 10;
>             # While para espera de resposta/sinal de processos filhos
>             while ( $gotone  < 1 && $timeout > 0) {
>                 sleep 1;
>                 $timeout=$timeout-1;
>             }
>
>             # if para encerrar processamento. Informa número de processos
> filhos que não responderam.
>             # teoricamente este if nunca deve ser processado. ESTE É O
> PROBLEMA.
>             if ($timeout <= 0) {
>                 logMsg("TIMEOUT!!! $kids checks não responderam a tempo.");
>                 $kids =0;
>                 next;
>             }
>
>
>             $gotone=$gotone-1;
>
>             #for para saber qual filho respondeu (sysread irá falhar até
> encontrar)
>             foreach my $checkID (@CHECKS) {
>
>                 my $win = "";
>                 my $rin = $win;
>                 vec($rin, fileno(*{$checkID}), 1) = 1;
>                 my $ein = $rin ;
>                 if (select($rin,$win,$ein,0)) {
>                     my $response;
>                     my $read = sysread($checkID,$response,512);
>                     #if (!defined($read)) {
>                      #   logMsg("ERROR (read pipe): $!");
>                     #}
>                     #else { next;}
>
>                    my $saida="";
>                     my $exit_value="";
>                     ($exit_value,$saida) = split(';',$response);
>                     $saida =~ s/[\r\n]//g;
>                     $saida = $saida;
>
>                     # Executa processamento da resposta
>
>                     close *{$checkID};
>                     $kids=$kids-1;
>                     last;
>                 }
>             }
>         }
>         my $kid;
>         do {
>             $kid = waitpid(-1, WNOHANG);
>         } while $kid > 0;
>     }
>
>
>
>
>
>
>
>
> ________________________________
> Veja quais são os assuntos do momento no Yahoo! + Buscados: Top 10 -
> Celebridades - Música - Esportes
> _______________________________________________
> Cascavel-pm mailing list
> Cascavel-pm em pm.org
> http://mail.pm.org/mailman/listinfo/cascavel-pm
>



-- 
"If you’ve never written anything thoughtful, then you’ve never had
any difficult, important, or interesting thoughts. That’s the secret:
people who don’t write, are people who don’t think."
_______________________________________________
Cascavel-pm mailing list
Cascavel-pm em pm.org
http://mail.pm.org/mailman/listinfo/cascavel-pm



      ____________________________________________________________________________________
Veja quais são os assuntos do momento no Yahoo! +Buscados
http://br.maisbuscados.yahoo.com
-------------- Próxima Parte ----------
Um anexo em HTML foi limpo...
URL: <http://mail.pm.org/pipermail/cascavel-pm/attachments/20100218/a0e4657b/attachment-0001.html>


Mais detalhes sobre a lista de discussão Cascavel-pm