Compartir un hash multidimensional entre hilos en Perl

De cara a la concurrencia es frecuente hacer un script que vaya lanzando hilos según sea necesario. Y no mucho menos habitual es también que tales hilos compartan algunas variables. Un ejemplo puede ser un sistema que recibe peticiones y mientras tanto las va lanzando en hilos.

A priori parece la mar de sencillo. Usando threads y threads::shared con un array o un hash se resuelve el asunto. Sin embargo si no hubiera más remedio que utilizar un hash y de más de una dimensión vendría el problema. Con shared se comparte un nivel del hash, de manera que si se tiene compartido %miscosas y se necesita ahora utilizar $miscosas{1339953221}{detalles}{algo} vamos a tener un error de vuelta del estilo invalid value for shared scalar.

Para ello hay dos soluciones posibles (sin tener en cuenta las de prescindir de un hash):

  • Declarar el hash con todos sus niveles de profundidad y entonces compartirlo. Aunque ello conlleva la pérdida de los datos que tuviera guardados. Además, en el caso de claves que tengan un valor dinámico esta puede no ser una solución trivial. Por ejemplo si la llave es el tiempo POSIX, como 1339953221.
  • Compartiendo llaves en cada nivel. Es la solución más complicada pero la más eficaz. Aunque en lo que yo la he utilizado ha resultado ser lenta y hacer gastar al script demasiado tiempo de ejecución con la línea de compartir. Sería algo así:
unless (defined $miscosas{1339953221} and defined $miscosas{1339953221}{detalles})
{
$miscosas{1339953221} = &share({});
$miscosas{1339953221}{detalles} = &share({});
$miscosas{1339953221}{detalles}{algo} = 'loquesea';
}

Así que si el tiempo es un factor muy importante a tener en cuenta puede que esta segunda solución no sea la más adecuada.

Fuentes → Stack Overflow y PerlMonks.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *