João,<div><br></div><div>Acho q não me expressei direito, o forks q eu falei é esse aqui:</div><div><a href="http://search.cpan.org/~rybskej/forks-0.34/lib/forks.pm">http://search.cpan.org/~rybskej/forks-0.34/lib/forks.pm</a></div>

<div><br clear="all">Just another Perl Hacker,<br>Fernando (SmokeMachine)<br><a href="http://perl-e.org">http://perl-e.org</a><br>
<br><br><div class="gmail_quote">Em 9 de julho de 2010 18:39, João André Simioni <span dir="ltr">&lt;<a href="mailto:jasimioni@gmail.com">jasimioni@gmail.com</a>&gt;</span> escreveu:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

Com 18 threads, cada thread faria, sequencialmente, 261 testes. E esse<br>
é o grande problema. Os testes com sucesso são rápidos, mas as falhas<br>
demoram<br>
cerca de 15 segundos (3 tentativas, com 1 segundo de timeout cada, com<br>
um intervalo de 3 segundos entre eles). Por isso cada thread não pode<br>
ter muitos elementos para testar (20 é um bom número).<br>
<br>
E eu preciso otimizar esse código para executar a cada um minuto.<br>
<br>
O que eu estou fazendo para contornar o problema é abrir 8 processos<br>
distintos com fork, e cada processo abre um conjunto de 30 threads.<br>
Mas mesmo assim não é uma solução &#39;elegante&#39;. O duro é ainda ver o<br>
pessoal de Java aqui do lado abrindo 800 threads tranquilamente hehe.<br>
<br>
Obrigado<br>
<br>
João André Simioni<br>
<br>
<br>
2010/7/9 Fernando Oliveira &lt;<a href="mailto:fernandocorrea@gmail.com">fernandocorrea@gmail.com</a>&gt;:<br>
<div><div></div><div class="h5">&gt; João,<br>
&gt; Vc não poderia, ao inves de criar varias vezes várias threads, criar um<br>
&gt; array shared com os ips q devem ser pingados e criar as 18 threads com um<br>
&gt; loop fazendo shift nesse array? No final vc teria apenas 18 threads...<br>
&gt; &lt;exemplo&gt;<br>
&gt; use threads;<br>
&gt; use threads::shared;<br>
&gt; my $max_threads = 18;<br>
&gt; my @ips : shared;<br>
&gt; my %result : shared;<br>
&gt; @ips = get_ips();<br>
&gt; for(1 .. $max_threads){<br>
&gt;    threads-&gt;create(\&amp;ping_thr)-&gt;detach;<br>
&gt; }<br>
&gt; sub ping_thr {<br>
&gt;    while( my $ip = shift @ips) {<br>
&gt;       $result{$ip} = testa_ping($ip);<br>
&gt;    }<br>
&gt; }<br>
&gt; &lt;/exemplo&gt;<br>
&gt; Isso é só um código de explicação, mas acho q ficou clara a minha ideia,<br>
&gt; não?<br>
&gt; outra coisa q vc pode tentar tb é não usar o threads, mas sim o forks,<br>
&gt; parece q a performance do forks é muito superior.<br>
&gt;<br>
&gt;<br>
&gt;<br>
&gt; Just another Perl Hacker,<br>
&gt; Fernando (SmokeMachine)<br>
&gt; <a href="http://perl-e.org" target="_blank">http://perl-e.org</a><br>
&gt;<br>
&gt;<br>
&gt; 2010/7/9 Lindolfo &quot;Lorn&quot; Rodrigues &lt;<a href="http://lorn.br" target="_blank">lorn.br</a>@<a href="http://gmail.com" target="_blank">gmail.com</a>&gt;<br>
&gt;&gt;<br>
&gt;&gt; João, estou com pressa agora e não posso detalhar muito o email, mas tente<br>
&gt;&gt; trocar sua solução de threads pelo POE<br>
&gt;&gt; <a href="http://search.cpan.org/~rcaputo/POE-1.289/lib/POE.pm" target="_blank">http://search.cpan.org/~rcaputo/POE-1.289/lib/POE.pm</a><br>
&gt;&gt; Vai parecer um pouco complicado no inicio, mas depois que pega o jeito<br>
&gt;&gt; você vai gostar :)<br>
&gt;&gt; Tem muitos exemplos aqui <a href="http://poe.perl.org/?POE_Cookbook" target="_blank">http://poe.perl.org/?POE_Cookbook</a> a maioria das<br>
&gt;&gt; coisas que fiz com ele eu usei como base algum script desse Cookbook.<br>
&gt;&gt; Enjoy!<br>
&gt;&gt;<br>
&gt;&gt; 2010/7/9 João André Simioni &lt;<a href="mailto:jasimioni@gmail.com">jasimioni@gmail.com</a>&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Caros,<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; tenho um script para testar cerca de 4700 equipamentos, usando ping.<br>
&gt;&gt;&gt; Queria usar cerca 250 threads para isso, então o que eu fiz foi<br>
&gt;&gt;&gt; quebrar o grupo de 4300 em grupos 18 elementos e abri uma thread para<br>
&gt;&gt;&gt; cada.<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Não há nenhum problema com o código, o que acontece é que o tempo de<br>
&gt;&gt;&gt; abertura das threads é muito alto. E quanto mais threads eu abro,<br>
&gt;&gt;&gt; maior o tempo para abertura das próximas. As primeiras abrem em 30ms,<br>
&gt;&gt;&gt; mas perto da thread 70 esse tempo já vai para quase 1 segundo.<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Vocês sabem como otimizar esse tempo de abertura? Ou alguma outra<br>
&gt;&gt;&gt; solução?<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Segue o output do script como exemplo:<br>
&gt;&gt;&gt; Para 4677 cpes, e 250 threads, tenho no final 246 grupos, com 19<br>
&gt;&gt;&gt; elementos cada<br>
&gt;&gt;&gt; Trying to create thread in Fri Jul  9 17:46:50 2010.61858<br>
&gt;&gt;&gt; Created thread 1 (1) - took 0.030138 seconds to create<br>
&gt;&gt;&gt; Trying to create thread in Fri Jul  9 17:46:50 2010.92080<br>
&gt;&gt;&gt; Created thread 2 (2) - took 0.042668 seconds to create<br>
&gt;&gt;&gt; Trying to create thread in Fri Jul  9 17:46:50 2010.134968<br>
&gt;&gt;&gt; Created thread 3 (3) - took 0.064245 seconds to create<br>
&gt;&gt;&gt; Trying to create thread in Fri Jul  9 17:46:50 2010.199430<br>
&gt;&gt;&gt; Created thread 4 (4) - took 0.082642 seconds to create<br>
&gt;&gt;&gt; Trying to create thread in Fri Jul  9 17:46:50 2010.282278<br>
&gt;&gt;&gt; Created thread 5 (5) - took 0.128257 seconds to create<br>
&gt;&gt;&gt; Trying to create thread in Fri Jul  9 17:46:50 2010.410769<br>
&gt;&gt;&gt; Created thread 6 (6) - took 0.136458 seconds to create<br>
&gt;&gt;&gt; Trying to create thread in Fri Jul  9 17:46:50 2010.547383<br>
&gt;&gt;&gt; Created thread 7 (7) - took 0.208085 seconds to create<br>
&gt;&gt;&gt; Trying to create thread in Fri Jul  9 17:46:50 2010.755594<br>
&gt;&gt;&gt; Created thread 8 (8) - took 0.173014 seconds to create<br>
&gt;&gt;&gt; Trying to create thread in Fri Jul  9 17:46:50 2010.928756<br>
&gt;&gt;&gt; Created thread 9 (9) - took 0.132713 seconds to create<br>
&gt;&gt;&gt; Trying to create thread in Fri Jul  9 17:46:51 2010.61608<br>
&gt;&gt;&gt; Created thread 10 (10) - took 0.127795 seconds to create<br>
&gt;&gt;&gt; Trying to create thread in Fri Jul  9 17:46:51 2010.189536<br>
&gt;&gt;&gt; Created thread 11 (11) - took 0.301836 seconds to create<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Obrigado<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; João André Simioni<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; #!/usr/bin/perl<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; use strict;<br>
&gt;&gt;&gt; use DBI;<br>
&gt;&gt;&gt; use Net::Ping;<br>
&gt;&gt;&gt; use Time::HiRes qw/usleep tv_interval gettimeofday/;<br>
&gt;&gt;&gt; use threads (&#39;yield&#39;, &#39;stack_size&#39; =&gt; 32*4096, &#39;exit&#39; =&gt;<br>
&gt;&gt;&gt; &#39;threads_only&#39;, &#39;stringify&#39;);<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; my $host = &#39;192.168.160.179&#39;;<br>
&gt;&gt;&gt; my $sid  = &#39;HOMOLOG&#39;;<br>
&gt;&gt;&gt; my $user = &#39;mac_user&#39;;<br>
&gt;&gt;&gt; my $pass = &#39;mac_user&#39;;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; my $dbh = DBI-&gt;connect(&quot;dbi:Oracle:host=$host;sid=$sid&quot;, $user, $pass,<br>
&gt;&gt;&gt; { AutoCommit =&gt; 1 });<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; my $sth = $dbh-&gt;prepare(&#39;SELECT CPE_ID, CLIENTE_ID, CPE_DESC,<br>
&gt;&gt;&gt; CPE_IP_WAN, CPE_NODE, CPE_IF FROM MAC_CPE WHERE CPE_PING = ? AND<br>
&gt;&gt;&gt; CPE_ATIVO = ?&#39;);<br>
&gt;&gt;&gt; $sth-&gt;execute(&#39;1&#39;, &#39;A&#39;);<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; my @cpes;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; while (my (@row) = $sth-&gt;fetchrow_array) {<br>
&gt;&gt;&gt;     push @cpes, [ @row ];<br>
&gt;&gt;&gt; }<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; $dbh-&gt;disconnect();<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; my $maxThreads = 250;<br>
&gt;&gt;&gt; my $total      = @cpes;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; my $cpePerThread = int($total / $maxThreads);<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; my @toMonitor;<br>
&gt;&gt;&gt; my $i = 0;<br>
&gt;&gt;&gt; my $c = 0;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; foreach my $cpe (@cpes) {<br>
&gt;&gt;&gt;     push @{$toMonitor[$i]}, $cpe;<br>
&gt;&gt;&gt;     $c++;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;     if ($c &gt; $cpePerThread) {<br>
&gt;&gt;&gt;         $i++;<br>
&gt;&gt;&gt;         $c = 0;<br>
&gt;&gt;&gt;     }<br>
&gt;&gt;&gt; }<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; print &quot;Para $total cpes, e $maxThreads threads, tenho no final $i<br>
&gt;&gt;&gt; grupos, com &quot;, scalar @{$toMonitor[0]}, &quot; elementos cada\n&quot;;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; sub processResult {<br>
&gt;&gt;&gt;     my $r = shift;<br>
&gt;&gt;&gt;     if (ref $r ne &#39;ARRAY&#39;) {<br>
&gt;&gt;&gt;         print STDERR &quot;Erro na thread\n&quot;;<br>
&gt;&gt;&gt;         return 0;<br>
&gt;&gt;&gt;     }<br>
&gt;&gt;&gt;     my ($result, $host, $ifs) = @$r;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; }<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; sub testeClient {<br>
&gt;&gt;&gt;     my $threadNum = shift;<br>
&gt;&gt;&gt;     my $cpeGroup  = shift;<br>
&gt;&gt;&gt;     foreach my $cpe (@{$cpeGroup}) {<br>
&gt;&gt;&gt;         my ($cpeId, $clientId, $cpeDesc, $cpeIp, $cpeNode, $cpeIf) =<br>
&gt;&gt;&gt; @$cpe;<br>
&gt;&gt;&gt;         my $pingOk = &amp;checkIp($cpeIp);<br>
&gt;&gt;&gt;         my $status = $pingOk ? &#39;RESPONDE&#39; : &#39;MORTO&#39;;<br>
&gt;&gt;&gt;         # print join(&quot;, &quot;, $threadNum, $cpeId, $clientId, $cpeDesc,<br>
&gt;&gt;&gt; $cpeIp, $cpeNode, $cpeIf, $status), &quot;\n&quot;;<br>
&gt;&gt;&gt;     }<br>
&gt;&gt;&gt;     # print &quot;Finishing thread $threadNum\n&quot;;<br>
&gt;&gt;&gt;     return([1, 0]);<br>
&gt;&gt;&gt; }<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; my $threadCount = 1;<br>
&gt;&gt;&gt; foreach my $cpeGroup (@toMonitor) {<br>
&gt;&gt;&gt;     print &quot;Trying to create thread&quot;;<br>
&gt;&gt;&gt;     my $t0 = [gettimeofday];<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;     print &quot; in &quot;, scalar localtime $t0-&gt;[0], &quot;.&quot;, $t0-&gt;[1], &quot;\n&quot;;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;     my $thr = threads-&gt;create({scalar =&gt; &#39;1&#39;}, &#39;testeClient&#39;,<br>
&gt;&gt;&gt; $threadCount, $cpeGroup);<br>
&gt;&gt;&gt;     my $elapsed = tv_interval ( $t0, [gettimeofday]);<br>
&gt;&gt;&gt;     print &quot;Created thread $thr ($threadCount) - took $elapsed seconds<br>
&gt;&gt;&gt; to create\n&quot;;<br>
&gt;&gt;&gt;     $threadCount++;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;     while (threads-&gt;list() &gt;= $maxThreads) {<br>
&gt;&gt;&gt;         my @joinable = threads-&gt;list(threads::joinable);<br>
&gt;&gt;&gt;         for (@joinable) {<br>
&gt;&gt;&gt;             my $r = $_-&gt;join();<br>
&gt;&gt;&gt;             &amp;processResult($r);<br>
&gt;&gt;&gt;         }<br>
&gt;&gt;&gt;         usleep(10000);<br>
&gt;&gt;&gt;     }<br>
&gt;&gt;&gt;     my $elapsed = tv_interval ( $t0, [gettimeofday]);<br>
&gt;&gt;&gt; }<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; while (threads-&gt;list()) {<br>
&gt;&gt;&gt;     my @joinable = threads-&gt;list(threads::joinable);<br>
&gt;&gt;&gt;     for (@joinable) {<br>
&gt;&gt;&gt;         my $r = $_-&gt;join();<br>
&gt;&gt;&gt;         &amp;processResult($r);<br>
&gt;&gt;&gt;     }<br>
&gt;&gt;&gt;     usleep(10000);<br>
&gt;&gt;&gt; }<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; sub checkIp {<br>
&gt;&gt;&gt;     my $ip = shift;<br>
&gt;&gt;&gt;     my $pingOk = 0;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;     eval {<br>
&gt;&gt;&gt;         for (1..3) {<br>
&gt;&gt;&gt;             my $ping = `/bin/ping -c 1 -w 1 $ip`;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;             if (grep { / 0% packet loss/ } $ping) {<br>
&gt;&gt;&gt;                 $pingOk = 1;<br>
&gt;&gt;&gt;                 return 1;<br>
&gt;&gt;&gt;             }<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;             if ($pingOk == 0) {<br>
&gt;&gt;&gt;                 my $p = Net::Ping-&gt;new(&#39;icmp&#39;);<br>
&gt;&gt;&gt;                 $p-&gt;service_check(1);<br>
&gt;&gt;&gt;                 if ($p-&gt;ping($ip, 1)) {<br>
&gt;&gt;&gt;                     $pingOk = 1;<br>
&gt;&gt;&gt;                     return 1;<br>
&gt;&gt;&gt;                 }<br>
&gt;&gt;&gt;             }<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;             if ($pingOk == 0) {<br>
&gt;&gt;&gt;                 my $p = Net::Ping-&gt;new(&#39;udp&#39;);<br>
&gt;&gt;&gt;                 $p-&gt;service_check(1);<br>
&gt;&gt;&gt;                 if ($p-&gt;ping($ip, 1)) {<br>
&gt;&gt;&gt;                     $pingOk = 1;<br>
&gt;&gt;&gt;                     return 1;<br>
&gt;&gt;&gt;                 }<br>
&gt;&gt;&gt;             }<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;             sleep 3;<br>
&gt;&gt;&gt;         }<br>
&gt;&gt;&gt;     };<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;     return $pingOk;<br>
&gt;&gt;&gt; }<br>
&gt;&gt;&gt; _______________________________________________<br>
&gt;&gt;&gt; Rio-pm mailing list<br>
&gt;&gt;&gt; <a href="mailto:Rio-pm@pm.org">Rio-pm@pm.org</a><br>
&gt;&gt;&gt; <a href="http://mail.pm.org/mailman/listinfo/rio-pm" target="_blank">http://mail.pm.org/mailman/listinfo/rio-pm</a><br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; --<br>
&gt;&gt; lorn at lornlab dot org<br>
&gt;&gt; Lindolfo &quot;Lorn&quot; Rodrigues<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; _______________________________________________<br>
&gt;&gt; Rio-pm mailing list<br>
&gt;&gt; <a href="mailto:Rio-pm@pm.org">Rio-pm@pm.org</a><br>
&gt;&gt; <a href="http://mail.pm.org/mailman/listinfo/rio-pm" target="_blank">http://mail.pm.org/mailman/listinfo/rio-pm</a><br>
&gt;<br>
&gt;<br>
&gt; _______________________________________________<br>
&gt; Rio-pm mailing list<br>
&gt; <a href="mailto:Rio-pm@pm.org">Rio-pm@pm.org</a><br>
&gt; <a href="http://mail.pm.org/mailman/listinfo/rio-pm" target="_blank">http://mail.pm.org/mailman/listinfo/rio-pm</a><br>
&gt;<br>
_______________________________________________<br>
Rio-pm mailing list<br>
<a href="mailto:Rio-pm@pm.org">Rio-pm@pm.org</a><br>
<a href="http://mail.pm.org/mailman/listinfo/rio-pm" target="_blank">http://mail.pm.org/mailman/listinfo/rio-pm</a><br>
</div></div></blockquote></div><br></div>