• Publicidad

Problema con multihilo

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Problema con multihilo

Notapor fgalves » 2006-10-13 09:31 @438

Hola a todos,

Tengo un módulo Perl que es ejecutado por muchos threads (creo que 4) en paralelo.
El caso es que tengo un contador:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $flatValidLines     = 0; # Number of valid lines
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

que es incrementado en una determinada función:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
sub printFlatDecodedLine {
    ...
    $flatValidLines++;
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


y otra función, llamada al final que imprime el valor de dicho contador:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
sub printFlatReport {
    ...
    my $nblines = $self->getFlatValidLines();
    if ($self->reopenReport($fileName) != 0 ) { return 1;}
    print $reportFd "TRAILER ".$nblines;
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


La función getFlatValidLines() devuelve el valor de la variable $flatValidLines.

El caso es que siempre me imprime 0, cuando en realidad ha ido incrementando. ¿Hay algun modo de proteger el valor y que ninguno de los threads lo meta a 0?

Gracias a todos,
Felipe
fgalves
Perlero nuevo
Perlero nuevo
 
Mensajes: 210
Registrado: 2006-09-25 13:54 @621

Publicidad

Notapor Perl user » 2006-10-13 09:58 @457

Que tal,

En efecto, el trabajo con aplicaciones concurrentes y/o paralelas las cuales acceden a un recurso compartido requiere de trabajo de sincronización. En el caso de Perl los recursos generalmente los marcas con el atributo 'shared' ( intuitivo no? ), que están dentro de thread::shared. También podrías buscar módulos dentro del namespace Thread:: para mecanismos de sincronización e IPC.

Échale un vistazo al perlthrtut, encontrarás muy valiosa información acerca de sincronización de datos ( recuerda tener en cuenta las race conditions ).

Sería mas útil que postearas también mas fragmentos de tu código.

Por otro lado como recomendación muy personal, evita el uso de threads en Perl. Hay varias razones entre las que destacan:

1) Habilitar el intérprete para el soporte de ithreads, el cual baja hasta un 40% del performance de cualquier aplicación.
2) Te da el mismo rendimiento que un fork ( porque de todos modos copia la imagen del prceso ).
3) Existen frameworks ( como POE ) que te ayudan a ejecutar eventos asíncronos de manera síncrona.

Solución? usa el punto número 3, usa forks o usa otro lenguaje.

Saludos,
Marco A. Manzo
[email protected]
http://www.unixmonkeys.com/amnesiac/
Perl Programming Language
Perl user
Maestro honorario
Maestro honorario
 
Mensajes: 271
Registrado: 2004-11-03 21:11 @924

De hecho no son realmente Threads

Notapor fgalves » 2006-10-13 10:22 @473

En realidad son forks y no threads los que acceden a dicha variable.
Eso supongo que cambia la filosofía del problema.

¿Alguien me puede echar una mano teniendo en cuenta que son forks?

¡¡Gracias!!
fgalves
Perlero nuevo
Perlero nuevo
 
Mensajes: 210
Registrado: 2006-09-25 13:54 @621

Notapor Perl user » 2006-10-13 10:28 @477

Mira... la solución es la misma, la implementación es diferente.

Ahora en vez de ver el perlthrtut, revisa el documento de perlipc.

Lo que requieres es sincronizar el acceso a esos datos mediante IPC (Inter-Process Communication), y podrás encontrar diferentes mecanismos dentro del namespace IPC:: en CPAN.

Muy posiblemente lo que estés buscando es un IPC::Semaphore.

Saludos,
Marco A. Manzo
[email protected]
http://www.unixmonkeys.com/amnesiac/
Perl Programming Language
Perl user
Maestro honorario
Maestro honorario
 
Mensajes: 271
Registrado: 2004-11-03 21:11 @924

Notapor explorer » 2006-10-13 10:48 @491

Si sólo hay un sitio donde la variable se pone a 0, ¿estás seguro de que la variable se está incrementando?
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

hay mas de un sitio donde se pone a cero

Notapor fgalves » 2006-10-13 11:17 @512

Hola Explorer,

De hecho, hay mas de un sitio donde se pone a cero.

En primer lugar, en el momento de declararla, se inicia a cero:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $flatValidLines     = 0; # Number of valid lines
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


y en segundo lugar, en dicha función, que es la función por la cual entran los 4 forks que son creados:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
sub initProjectionValues {
        my $self  = shift; # Skip the class name. We use Perl "object" Class methods.

        my $projInitParams  = $_[0];

        # if defined we change the temporary result file name headers else we use default ones.
        if (defined $projInitParams->{ProjectionHeader}) {
                $xmlTmpProjFileName = $projInitParams->{ProjectionHeader}."_"."Outbrs_XML.rpt";
                $flatTmpProjFileName = $projInitParams->{ProjectionHeader}."_"."Outbrs_Flat.rpt";
        }

        # if defined we change the working directory.
        if (defined $projInitParams->{WorkingDirectory}) {
                $workingDirectory = $projInitParams->{WorkingDirectory};
        }

        $xmlProcessedLines  = 0;
        $xmlValidLines      = 0;
        $flatProcessedLines = 0;
        $flatValidLines     = 0;

}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4



El hecho es que hace un rato, puse en comentarios la inicialización de dicha función, pero me seguía imprimiendo el TRAILER a 0.
Este sí que es un problema de locos.
Creía que había alguna sentencia del tipo "static" como en C, para que el valor de dicha variable se mantuviera.

Un saludo,
Felipe
fgalves
Perlero nuevo
Perlero nuevo
 
Mensajes: 210
Registrado: 2006-09-25 13:54 @621

Notapor explorer » 2006-10-13 11:46 @532

Si son forks, entonces son 4 procesos independientes. Cada uno tendrá su propia copia de la variable y no interferirán entre ellos salvo que el programa así lo pida.

Yo creo que si la variable es 0 es porque nunca cambia.

Prueba a poner en initProjectionValues que la variable valga -2, por ejemplo. a ver qué pasa :-)
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor Perl user » 2006-10-13 11:53 @537

Efectivamente explorer,

Los 4 procesos ( creados con fork ) son imagenes de proceso completamente independientes, apartir de la llamada al fork, la imagen del proceso que la llamó copia los recursos necesarios para generar el nuevo proceso, eso incluye variables, fd's y memoria.

Por lo tanto, apartir de alli cada proceso tiene su propio juego de esa variable.

Qué significa esto? Lo que ya le expliqué anteriormente, necesita un mecanismo de IPC para poder sincronizar y usar datos compartidos entre cada uno de los procesos.

Si quiere una porción de memoria puede utilizar Shared Memory (shmem).

Hay diferentes mecanismos, es necesario que lea cual es el que mejor le conviene y por qué...

Con el código que muestra tampoco puedo decirle a ciencia cierta que es lo que puede necesitar, ya que no ha copiado nada que tenga que ver con el contexto de como es creado cada proceso.

Saludos,
Marco A. Manzo
[email protected]
http://www.unixmonkeys.com/amnesiac/
Perl Programming Language
Perl user
Maestro honorario
Maestro honorario
 
Mensajes: 271
Registrado: 2004-11-03 21:11 @924

puedo depurar ese codigo en windows con eclipse o dzperl?

Notapor fgalves » 2006-10-15 08:58 @415

Simple curiosidad e ignorancia mezcladas: ¿puedo depurar dicho código en algun IDE windows del estilo Eclipse+Epic o Dzperl, o estoy obligado a usar Linux por las llamadas al sistema fork?
Me imagino que debo usar Linux, y en ese caso supongo que no sería mala idea usar Eclipse con Epic, aunque preferiría poder hacerlo desde Windows.

Gracias de antemano,
Felipe
fgalves
Perlero nuevo
Perlero nuevo
 
Mensajes: 210
Registrado: 2006-09-25 13:54 @621

Notapor explorer » 2006-10-15 09:57 @456

Si las llamadas son 'fork', entonces, efectivamente, deberás usar un sistema operativo compatible Unix.

Y para depurar, puedes usar el Eclipse+epic, claro, pero recuerda que el Perl lleva su propio depurador: perl -d
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Siguiente

Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: Google [Bot] y 0 invitados