[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