2010-09-13 14 views
8

Estoy intentando compartir un hash multidimensional sobre varios subprocesos. Este hash tiene 2 pares de llaves conectadas, necesito saber si ya están conectadas, si no lo están, necesito conectarlas, si no, no hay necesidad de ir a la base de datos.Perl: subprocesamiento con hash multidimensional compartido

use threads; 
use threads::shared; 

my %FLUobject2param : shared =(); 

#Start a new thread for every available processor 
for (my $i=0;$i<$PROCESSORS;$i++) { 
    threads->new(\&handlethread); 
} 
#Catch if these threads end 
foreach my $onthr (threads->list()) { 
    $onthr->join(); 
} 

sub handlethread{ 
    ... 
    if(not defined $FLUobject2param{$objectID}{$paramID}){ 
     $dbh->getObject2Param($objectID,$paramID); 
     $FLUobject2param{$objectID}{$paramID} = 1; 
    } 
} 

sigo obteniendo el error Invalid value for shared scalar en la línea
if(not defined $FLUobject2param{$objectID}{$paramID}){

Al parecer, esto tiene que ver con hilos de Perl :: compartida sólo que le permite compartir un único nivel de estructura compartida.

¿Cómo podría seguir siendo capaz de comprobar si esta combinación ya se utiliza en múltiples hilos?

Respuesta

8

Autovivificación es su amigo la mayor parte del tiempo, pero debe tener cuidado con los valores compartidos. Modificar handlethread:

sub handlethread{ 
    # ... 
    unless (exists $FLUobject2param{$objectID} && 
      exists $FLUobject2param{$objectID}{$paramID}) 
    { 
     $dbh->getObject2Param($objectID,$paramID); 
     $FLUobject2param{$objectID} = &share({}); 
     $FLUobject2param{$objectID}{$paramID} = 1; 
    } 
} 

Esto se debe hacer un documented limitation:

Las variables compartidas sólo pueden escalares de la tienda, los árbitros de las variables compartidas o árbitros de datos compartidos ...

el código anterior comprueba las claves hash por separado para evitar la autovibración, que plantará una referencia hash vacía no compartida en $FLUobject2param{$objectID} si aún no existe.

Dentro del condicional, primero construimos el andamio apropiado y luego le asignamos el valor. Una vez más, la autovibración normalmente maneja esto para ti, pero compartir nos obliga a ser más deliberados.