Historia del tema:
El soporte para trabajar con hilos apareció en Perl 5.005, pero debido a las peculiaridades de la implementación del lenguaje, permaneció experimental durante mucho tiempo y estuvo acompañado de numerosos errores y limitaciones. A partir de Perl 5.8, el módulo threads (y threads::shared) se volvió lo suficientemente estable para tareas serias, sin embargo, el modelo de hilos de Perl es muy diferente al de muchos otros lenguajes de programación: cada hilo recibe su propia copia de todas las variables, y solo las estructuras declaradas explícitamente a través de threads::shared están disponibles para el acceso compartido.
Problema:
Las variables "normales" no son visibles entre hilos debido a la semántica de copy-on-write. Intentar compartir datos sin threads::shared conduce a la desincronización del estado. El uso incorrecto de bloqueos puede dar lugar a condiciones de carrera, deadlocks o cambios inconsistentes.
Solución:
Para compartir variables, declara variables compartidas a través de use threads::shared. Bloquea el acceso a los datos compartidos utilizando lock, especialmente si varios hilos leen/escriben simultáneamente. Usa los métodos join/detach para gestionar el ciclo de vida de los hilos. Para estructuras complejas, declara cada elemento como shared por separado, ya que solo el "nivel superior" no garantiza la completa seguridad en hilos.
Ejemplo de código:
use threads; use threads::shared; my $counter :shared = 0; my @threads; for (1..10) { push @threads, threads->create(sub { for (1..1000) { lock($counter); ++$counter; } }); } $_->join() for @threads; print "Counter: $counter ";
Características clave:
¿Proporciona :shared seguridad en hilos sin un lock adicional?
No. El atributo :shared proporciona acceso a la variable entre hilos, pero los cambios (como ++ o --) no son atómicos. Se requiere un lock para cada sección crítica.
¿Se puede compartir una estructura compleja (array de hashes) entre hilos con una sola directiva :shared?
No. Solo el "nivel superior" del array o hash será shared. Cada elemento anidado también debe ser compartido, de lo contrario, las estructuras internas no serán visibles para otros hilos.
¿Puede un hilo matar a otro hilo llamando a exit?
No. exit termina el proceso completo, no un hilo individual. La parada de un hilo se realiza a través de exit dentro del hilo o se gestiona con la lógica de join/detach.
Dos hilos incrementan $counter :shared simultáneamente sin lock. El resultado final es menor de lo esperado (problema típico de lost update).
Ventajas:
Desventajas:
Implementación de lock en cada cambio de la variable compartida. Para estructuras grandes, hacer lock anidado elemento por elemento.
Ventajas:
Desventajas: