[caracas-pm] Hilos en Perl
Carlos Ramírez
carlosyr at gmail.com
Mon Nov 25 07:26:37 PST 2013
Saludos Alberto,
Cuando ejecutas la función "create" en un thread, esta automáticamente
comienza a ejecutarse, sin esperar por más nada.
El join, se utiliza para esperar la finalización de un thread
ejecutándose (como te has dado cuenta) o para obtener el resultado de
un thread que finalizó Si ejecutas un thread y el programa en perl
termina sin realizar el join o un detach perl te dará una alerta (y
finalizará los threads). Ejecuta el siguiente programa para que veas a
que me refiero.
Nota: voy a copiar una sola vez la función "cuenta" porque es la misma
para todos los ejemplos y creo que la mejor pista para lo que quieres
está en el último :-D
#!/usr/bin/perl
use strict;
use threads;
my $thread = threads->create('cuenta',0,3,1);
while ($thread->is_running()){
sleep 1;
}
sub cuenta
{
my ($inicio,$final,$paso) = @_;
if($inicio > $final || $paso < 0){ warn "# cuenta : no puedo
contar asi ($inicio,$final,$paso)...\n"; }
for(my $i=$inicio;$i<=$final;$i+=$paso)
{
print "$i\n";
sleep(1);
}
}
---
Ahora bien,ejecuta el mismo programa pero con una simple modificación:
---
#!/usr/bin/perl
use strict;
use threads;
my $thread = threads->create('cuenta',0,3,1);
while ($thread->is_running()){
sleep 1;
}
$thread->join(); #Obtengo el resultado si lo hay.
#sub cuenta.....
----
Ahora, el mismo programa pero con un detach
----
#!/usr/bin/perl
use strict;
use threads;
my $thread = threads->create('cuenta',0,3,1);
$thread->detach(); #El thread no tratará devolverá su estado de
ejecución, al terminar finalizará
while ($thread->is_running()){
sleep 1;
}
#sub cuenta.....
---
Ahora ejecutando dos "hilos".
---
#!/usr/bin/perl
use strict;
use threads;
my $thread1 = threads->create('cuenta',0,3,1); #Cuento desde el 0 hasta el 3
my $thread2 = threads->create('cuenta',10,13,1); #Cuento desde el 10 hasta el 13
$thread1->detach(); #Este thread termina y no me interesa obtener su
código salida o resultado
$thread2->detach(); #Mismo que lo anterior.
while ($thread1->is_running() || $thread2->is_running()){
sleep 1;
}
#sub cuenta.....
--
Otro ejemplo
--
#!/usr/bin/perl
use strict;
use threads;
for(my $i=0;$i<9;$i++){
threads->create('cuenta',$i*10,($i*10)+$i+1,1); } #Se crean 10
threads, la primera contará hasta 1, la segunda hasta 2 y así
sucesivamente.
while(my $threads=threads->list(threads::running)){
print "Threads ejecutandose: $threads \n";
sleep 1;
}
map { $_->join() } threads->list(threads::joinable); #Todas las
threads finalizaron pero aún no han "devuelto" estado.
#sub cuenta.....
--
Tu script
--
my @fotos = readdir($dir);
for my $pic (@fotos) {
if ($pic =~ m/jpe*g$/i) {
say "Trabajando con $pic";
until (threads->list(threads::running) < 5){ sleep 1; } # máximo
cinco hilos.
threads->create('procesar', $pic);
map {$_->join()} threads->list(threads::joinable); #Termino los
threads que ya finalizaron hasta ahora,
}
}
while(threads->list(threads::running)){ sleep 1; } #Hay que esperar
que los últimos 5 threads finalicen.
map {$_->join()} threads->list(threads::joinable); #Finalizo los
threads terminados.
Creo que así van los tiros, No he trabajado mucho con threads, comenta
si te sirve.
Saludos.
El 2 de noviembre de 2013 00:32, Alberto Mijares <amijaresp at gmail.com> escribió:
>
> Hola lista,
>
> Estoy jugando un poco, de manera didàctica, con el módulo "threads" de
> Perl. Quería ver qué tanto podía mejorar un script sencillo que tengo
> para redimencionar fotos.
>
> El script original tenía algo como
....
More information about the caracas-pm
mailing list