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