En el ejemplo que sigue se muestran dos threads o hilos que comparten un
recurso: la variable $locked
la cuál ambas modifican.
El ejemplo sirve para ilustrar la ventaja de usar una clausura:
La variable $locked
esta clausurada y compartida
por las subrutinas tutu
y titi
:
$ cat -n shared2.pl 1 #!/usr/bin/perl -w 2 use strict; 3 use threads; 4 use threads::shared; 5 { 6 my $locked : shared = 0; 7 8 sub tutu { sleep(rand(3)); lock($locked); $locked++; $locked } 9 sub titi { sleep(rand(3)); lock($locked); $locked--; $locked } 10 } 11 12 my $t = threads->new(\&tutu); # creamos la thread 13 my $rm = titi(); 14 my $rs = $t->join(); # sincronizamos las dos threads 15 print "Maestro: $rm\nEsclavo: $rs\n";El paquete
threads
, usado en la línea 3, nos proporciona las herramientas
para la creación de threads. El método new()
(línea 12) toma
una referencia a una subrutina y crea una nueva thread que ejecuta
concurrentemente la subrutina referenciada.
Si se hubiera necesitado, es posible pasar parámetros a la subrutina como parte de la fase de arranque:
$thr = threads->new(\&tutu, "Param 1", "Param 2", 4);
El método join()
usado en la línea 28 retorna cuando
la thread $t
termina. Además recolecta y retorna
los valores que la thread haya retornado.
En general es una lista:
@ReturnData = $t->join;
Cuando se crea un nuevo hilo, todos los datos asociados con el hilo actual
se copian en el nuevo. Por tanto, las variables son, por defecto privadas a la
thread. En la mayoría de los casos se pretende que exista alguna forma
de comunicación entre los hilos, para lo cual es conveniente disponer
de mecanismos para hacer que ciertas variables sean compartidas por los hilos.
Esta es la función del módulo threads::shared
y del atributo
shared
(línea 6).
La función lock
proporcionada por el módulo threads::shared
nos permite sincronizar el acceso a la variable. El cerrojo se libera
al salir del contexto léxico en el que se produjo el lock
. En el ejemplo,
se libera al salir de la correspondiente subrutina. No existe
por tanto una función unlock
.
Veamos una ejecución:
$ ./shared2.pl Maestro: 0 Esclavo: 1 $ ./shared2.pl Maestro: -1 Esclavo: 0