<html><head><style type="text/css"><!-- DIV {margin:0px;} --></style></head><body><div style="font-family:times new roman,new york,times,serif;font-size:12pt"><div>Para aqueles que tiverem dúvidas, segue pagina de onde retirei a estrutura do código.<br><br><span><a target="_blank" href="http://www.wellho.net/solutions/perl-controlling-multiple-asyncronous-processes-in-perl.html">http://www.wellho.net/solutions/perl-controlling-multiple-asyncronous-processes-in-perl.html</a></span><br></div><div style="font-family: times new roman,new york,times,serif; font-size: 12pt;"><br><br><div style="font-family: arial,helvetica,sans-serif; font-size: 13px;"><font face="Tahoma" size="2"><hr size="1"><b><span style="font-weight: bold;">De:</span></b> Daniel de Oliveira Mantovani &lt;daniel.oliveira.mantovani@gmail.com&gt;<br><b><span style="font-weight: bold;">Para:</span></b> Cascavel Perl Mongers &lt;cascavel-pm@pm.org&gt;<br><b><span style="font-weight:
 bold;">Enviadas:</span></b> Quinta-feira, 18 de Fevereiro de 2010 13:11:16<br><b><span style="font-weight: bold;">Assunto:</span></b> Re: [Cascavel-pm] Problema com pipe<br></font><br>Você acha mesmo que executar 80 comandos de uma vez e elevar o load da<br>máquina ao infinito e além vai resolver o problema ?<br><br>Me parece que o problema é muito além de um script ou dois. Uma hora<br>esse "treco" vai parar, se já é que não para. Agora é a hora de<br>"sentar, pensar e refazer"<br><br>Da uma lida em: perldoc perlipc vai te ajudar nesse seu "treco".<br><br>2010/2/18 Gabriel Sancinetti &lt;<a ymailto="mailto:gabrielssan@yahoo.com" href="mailto:gabrielssan@yahoo.com">gabrielssan@yahoo.com</a>&gt;:<br>&gt; Olá,<br>&gt;<br>&gt; Estou trabalhando com perl há alguns meses e recentemente me deparei com um<br>&gt; grande desafio.(pelo menos para mim).<br>&gt; Não sei se esta lista é a adequada, mas ja gastei 4 semanas pesquisando no<br>&gt; google
 e nada de solução.<br>&gt;<br>&gt; Enfim...<br>&gt; Preciso reduzir o tempo de execução de um script de aproximadamente 50<br>&gt; minutos para 8 minutos.<br>&gt; 1 - Este scrip faz mais de 2 mil "chamadas externas" de sistema operacional<br>&gt; ( `comando` ) com timeout de 5 a 10 seguntos.<br>&gt; 2 - É necessário processar o STDOUT e EXIT STATUS do comando em um processo<br>&gt; único não necessáriamente em sequencia.<br>&gt;<br>&gt; A solução com certeza deve implementar alguma forma de paralelismo.<br>&gt; Não consegui desenvolver uma forma de utilizar "open" no script. Então perdi<br>&gt; para uma solução de baixo nível.<br>&gt;<br>&gt; Encontrei uma solução que quase atendeu minhas expectativas, mas estou com<br>&gt; problemas de nível de Sistema Operacional nela.<br>&gt;<br>&gt; Recomendo que deem uma olhada no código pois agora irei descrever o problema<br>&gt; deste código.<br>&gt;<br>&gt; O meu problema é a ocorrencia de
 grande quantidade de TIMEOUTs, isto é, o<br>&gt; processo pai não recebe/processa as respostas dos filhos.<br>&gt; Separei as chamadas de sistema em grupos de 80 comandos.<br>&gt; Quando executo o script sem o sleep tanto no processo pai quanto no processo<br>&gt; filho chego q ter mais de 50% de perda de respostas, (TIMEOUT)<br>&gt; Conforme adiciono tempo ao sleep no processo filho, consigo reduzir a<br>&gt; quantidade de TIMEOUTS considerávelmente, mas longe do satizfatório.<br>&gt; Já quando adiciono o sleep antes do fork do processo filho a ocorrencia de<br>&gt; TIMEOUTs cai a menos de 0.5%, mas o tempo de execução do script se aproxima<br>&gt; do original (40 minutos).<br>&gt;<br>&gt; Acredito que meu problema esteja no processamento do sinal (kill), mas<br>&gt; também pode ser no pipe. Não acredito que seja no pipe pois não ocorre erros<br>&gt; no syswrite e no sysread, etc.<br>&gt; Já estou quase certo de que terei que refazer tudo de
 outro jeito, mas estou<br>&gt; sem idéias e preciso da opinião de pessoas mais experientes.<br>&gt;<br>&gt; Então, agradeço desde já a atenção de vocês e espero susgestões para<br>&gt; corrigir este script ou para refazer de outro jeito.<br>&gt;<br>&gt; Cordialmente,<br>&gt;<br>&gt; Gabriel<br>&gt;<br>&gt; ps: Ignorem erros de sintaxe e identação pois editei o codigo no corpo da<br>&gt; mensagem.<br>&gt;<br>&gt; #########################################################################################################<br>&gt; my $gotone;<br>&gt; sub doneit {<br>&gt; &nbsp;&nbsp;&nbsp; $gotone=$gotone+1;<br>&gt; #&nbsp;&nbsp;&nbsp; logMsg("Got one! ($gotone)");<br>&gt; }<br>&gt;<br>&gt; $SIG{USR1} = \&amp;doneit;<br>&gt; my $parent = $$;<br>&gt; $kids=0;<br>&gt; $gotone=0;<br>&gt;<br>&gt; #Para não sobrecarregar o servidor, a lista de comandos é dividida em grupos<br>&gt; de 80. (@CHECKS = (cmd1 .. cmd80))<br>&gt; foreach my $checkID (@CHECKS)
 {<br>&gt;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; pipe *{$checkID},PIPEN;<br>&gt;<br>&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #Espera do processo pai antes de cada fork para testes<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; # Este tempo de espera é diferencial na ocorrencia da falha<br>&gt; #&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sleep(10);<br>&gt;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $PIDs{$checkID} = fork();<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (not defined $PIDs{$checkID}) {<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; logMsg("ERROR: Fork FAILURE!!!");<br>&gt;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } elsif ($PIDs{$checkID} == 0) {<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; # Processo
 filho executa espera diminuindo probalidade de<br>&gt; sobrecarga de respostas para processo pai.<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; my $random_number = rand();<br>&gt; # &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; my $random_wait = $random_number*3;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sleep($random_wait);<br>&gt;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; my $saida;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $saida = `cmdN`;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; my $exit_value = $? &gt;&gt; 8;<br>&gt;<br>&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; #Escreve saida no pipe para processo pai.<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
 &nbsp;&nbsp;&nbsp; my $write = syswrite PIPEN, "$exit_value;$saida";<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (!defined($write)) {<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; logMsg("ERROR (write pipe): $!");<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&gt;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; close *{$checkID};<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; kill "USR1",$parent;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; exit();<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; # fim do processo filho<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
 &nbsp;&nbsp;&nbsp; # Contagem de número de processos filhos no pai (80)<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $kids++;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&gt;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; # While para processamento de respostas dos processos filhos<br>&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # deve ser garantido que todos filhos serão processados<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; while ($kids &gt; 0) {<br>&gt;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; # Aguarda 10 segundos depois de receber ultimo sinal (USR1).<br>&gt; $gotone é uma variavel global que contabiliza o numero de processos filhos<br>&gt; que ja responderam. Esta variavel é decrementada de acordo com o<br>&gt; processamento dos filhos para controle de TIMEOUT.<br>&gt; &nbsp;&nbsp;&nbsp;
 &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; my $timeout = 10;<br>&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # While para espera de resposta/sinal de processos filhos<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; while ( $gotone&nbsp; &lt; 1 &amp;&amp; $timeout &gt; 0) {<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; sleep 1;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $timeout=$timeout-1;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&gt;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # if para encerrar processamento. Informa número de processos<br>&gt; filhos que não responderam.<br>&gt; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # teoricamente este if nunca deve ser processado. ESTE É O<br>&gt; PROBLEMA.<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
 &nbsp;&nbsp;&nbsp; if ($timeout &lt;= 0) {<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; logMsg("TIMEOUT!!! $kids checks não responderam a tempo.");<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $kids =0;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; next;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&gt;<br>&gt;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; $gotone=$gotone-1;<br>&gt;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; #for para saber qual filho respondeu (sysread irá falhar até<br>&gt; encontrar)<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; foreach my $checkID (@CHECKS) {<br>&gt;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; my $win = "";<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;
 &nbsp;&nbsp;&nbsp; &nbsp;my $rin = $win;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;vec($rin, fileno(*{$checkID}), 1) = 1;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;my $ein = $rin ;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;if (select($rin,$win,$ein,0)) {<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;my $response;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; my $read = sysread($checkID,$response,512);<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; #if (!defined($read)) {<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; #&nbsp;&nbsp; logMsg("ERROR (read pipe): $!");<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;
 &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; #}<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; #else { next;}<br>&gt;<br>&gt; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; my $saida="";<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;my $exit_value="";<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;($exit_value,$saida) = split(';',$response);<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;$saida =~ s/[\r\n]//g;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;$saida = $saida;<br>&gt;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; # Executa processamento da
 resposta<br>&gt;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; close *{$checkID};<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; $kids=$kids-1;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; last;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; }<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; }<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; my $kid;<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;do {<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;$kid = waitpid(-1, WNOHANG);<br>&gt; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp; &nbsp;} while $kid &gt; 0;<br>&gt; &nbsp;&nbsp;&nbsp; }<br>&gt;<br>&gt;<br>&gt;<br>&gt;<br>&gt;<br>&gt;<br>&gt;<br>&gt;<br>&gt;
 ________________________________<br>&gt; Veja quais são os assuntos do momento no Yahoo! + Buscados: Top 10 -<br>&gt; Celebridades - Música - Esportes<br>&gt; _______________________________________________<br>&gt; Cascavel-pm mailing list<br>&gt; <a ymailto="mailto:Cascavel-pm@pm.org" href="mailto:Cascavel-pm@pm.org">Cascavel-pm@pm.org</a><br>&gt; <a href="http://mail.pm.org/mailman/listinfo/cascavel-pm" target="_blank">http://mail.pm.org/mailman/listinfo/cascavel-pm</a><br>&gt;<br><br><br><br>-- <br>"If you’ve never written anything thoughtful, then you’ve never had<br>any difficult, important, or interesting thoughts. That’s the secret:<br>people who don’t write, are people who don’t think."<br>_______________________________________________<br>Cascavel-pm mailing list<br><a ymailto="mailto:Cascavel-pm@pm.org" href="mailto:Cascavel-pm@pm.org">Cascavel-pm@pm.org</a><br><a href="http://mail.pm.org/mailman/listinfo/cascavel-pm"
 target="_blank">http://mail.pm.org/mailman/listinfo/cascavel-pm</a><br></div></div>
</div><br>


      <hr size=1>Veja quais são os assuntos do momento no Yahoo! + Buscados: <a href="http://br.rd.yahoo.com/mail/taglines/mail/*http://br.maisbuscados.yahoo.com/">Top 10</a> - <a href="http://br.rd.yahoo.com/mail/taglines/mail/*http://br.maisbuscados.yahoo.com/celebridades/">Celebridades</a> - <a href="http://br.rd.yahoo.com/mail/taglines/mail/*http://br.maisbuscados.yahoo.com/m%C3%BAsica/">Música</a> - <a href="http://br.rd.yahoo.com/mail/taglines/mail/*http://br.maisbuscados.yahoo.com/esportes/">Esportes</a></body></html>