• Publicidad

threads y hash de más de un nivel

Así que programas sin strict y las expresiones regulares son otro modo de hablar. Aquí encontrarás respuestas de nivel avanzado, no recomendable para los débiles de corazón.

threads y hash de más de un nivel

Notapor ufaria » 2011-07-11 14:26 @643

Tengo un script que parsea log que le entra por un socket udp y estoy llegando
el límite de un procesador en una máquina de cuatro.

Estuve pensando la mejor manera de aprovechar los cuatro procesadores y finalmente
me decidí a hacerlo multihilo porque suponía que usar el mismo segmento de memoria
(teniendo en cuenta que ithreads no mantiene el mismo segmento) para pasar datos
entre hilos es la forma más 'eficaz' que veo.

He descartado la opción de crear hijos y pasar datos por sockets o con un segmento
de memoria compartido por diferentes razones.

Pero me encuentro que no puedo compartir un hash indexado de más de un nivel de forma
sencilla sin hacer verdaderas locuras que echan al traste la velocidad que quiero
usando threads.

He visto incluso las varias implementaciones de threads de Perl y no me terminan de
convencer ¿Alguien ha probado coro? ¿Usa correctamente todos los procesadores de una
máquina?

En fin, que la pregunta aquí es: ¿alguien se ha pegado con este problema antes? ¿alguna
idea que no sea $hash{'uno'}{'dos'} = &share({}); ?

Estoy pensando también en usar el módulo Storable pero supongo que al final es añadir
capas y capas.

Gracias.
ufaria
Perlero nuevo
Perlero nuevo
 
Mensajes: 4
Registrado: 2011-07-11 14:12 @633

Publicidad

Re: threads y hash de más de un nivel

Notapor explorer » 2011-07-11 18:05 @795

Bienvenido a los foros de Perl en español, ufaria.

Lo que no acabo de ver es qué tipo de trabajo quieres repartir entre los procesadores. ¿El trabajo de procesamiento del registro?
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

Re: threads y hash de más de un nivel

Notapor ufaria » 2011-07-12 02:00 @125

Pues lo más pesado del script son todas las expresiones regulares que
paso a los logs, así que lo reparto entre los procesadores y luego
uno las estadísticas.
ufaria
Perlero nuevo
Perlero nuevo
 
Mensajes: 4
Registrado: 2011-07-11 14:12 @633

Re: threads y hash de más de un nivel

Notapor salva » 2011-07-12 04:36 @233

ufaria escribiste:He visto incluso las varias implementaciones de threads de Perl y no me terminan de convencer ¿Alguien ha probado coro? ¿Usa correctamente todos los procesadores de una máquina?

No, Coro solo es capaz de usar un procesador de la máquina.

Yo en tu caso vería si es posible dividir el trabajo entre varios procesos (o sea, usando fork en vez de threads) y al final realizar un proceso de consolidación de los resultados.
Avatar de Usuario
salva
Perlero nuevo
Perlero nuevo
 
Mensajes: 200
Registrado: 2008-01-03 15:19 @680

Re: threads y hash de más de un nivel

Notapor explorer » 2011-07-12 12:30 @562

A ver si funciona la siguiente propuesta...

El programa va escuchando y almacenando lo que le va llegando por el UDP (pero no lo procesa).

Cuando se da una de estas dos circunstancias:
a) Han pasado N ms y no se ha recibido ninguna nueva entrada
b) Hemos almacenado X líneas de registro
entonces creamos un fork() con un proceso encargado de sacar las estadísticas de las líneas almacenadas.

La idea es que cuanto más información entre, vamos creando procesos según esa demanda.

Calculamos el valor de X como el número de líneas que ahora procesamos en un solo procesador, dividido entre el número de procesadores que queremos ocupar.

Edito: se me adelantó salva.
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

Re: threads y hash de más de un nivel

Notapor ufaria » 2011-07-12 12:48 @575

Lo cierto es que entran miles de líneas por segundo y lo que hago es escuchar el socket y en el momento que entra una, la envío por una queue al thread que corresponda ( hago un round-robin ) prima que sea muy rápido el proceso. Luego cada hilo parsea y saca datos estadísticos estructurados en un hash multinivel ( que es como lo hago con un solo procesador y funciona bien ) mantengo las estadísticas en el hilo master y cada x segundos bloqueo el hash para sincronizar. Teóricamente todo es correcto solo que al salvar en hash compartido en un punto por debajo del primer nivel sin haberlo definido antes se muere el hilo, porque no se puede hacer eso.

Además no puedo hacer algo tan simple como esto:

if (!$hash{'uno'}{'dos'}) { <--- aquí peta.
$hash{'uno'}{'dos'} = &share({});
}
$hash{'uno'}{'dos'} = 1;

(tampoco puedo con las funciones exists, is_shared, etc)

porque al ser un hash shared no puedo acceder a un nivel que
todavía no existe ni siquiera para preguntar si existe.
Es un poco la pescadilla que se muerde la cola. Tengo que saber
de antemano qué niveles van a existir y precompartirlos cosa
que no puedo porque el hash se genera de forma dinámica.

Solo se me ocurre guardar en la variable datos estructurados
con el módulo Storable pero me parece que así pierdo la velocidad
que ganaría directamente con los threads.

No sé si me explico...
ufaria
Perlero nuevo
Perlero nuevo
 
Mensajes: 4
Registrado: 2011-07-11 14:12 @633

Re: threads y hash de más de un nivel

Notapor explorer » 2011-07-12 16:01 @709

Según la documentación, esto funcionaría (pero no lo he probado):
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my %hash :shared;
my %hdos :shared;

$hdos{'dos'} = 1;

$hash{'uno'} = \%hdos;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Es decir, la regla básica es que solo se permiten valores simples o referencias a variables compartidas (shared) (sacado de la sección Shared And Unshared Data de perlthrtut).

El problema... ya se ve... que tendrías que crear hash secundarios compartidos, por adelantado.

Otra opción: eliminar el segundo nivel:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my %hash :shared;
$hash{'uno|dos'} = 1;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
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

Re: threads y hash de más de un nivel

Notapor ufaria » 2011-07-13 16:35 @733

Al final lo he solucionado rehaciendo la forma de trabajar con el hash y definiendo todo desde un principio.

Pierdo un poco de velocidad y flexibilidad, pero bueno, funciona.

La verdad es que este tema de los hilos en Perl está poco pulido
comparándolo con otros lenguajes. Bueno, es lo que hay.

Gracias por la ayuda.

Saludos.
ufaria
Perlero nuevo
Perlero nuevo
 
Mensajes: 4
Registrado: 2011-07-11 14:12 @633

Re: threads y hash de más de un nivel

Notapor salva » 2011-07-14 01:56 @122

ufaria escribiste:La verdad es que este tema de los hilos en Perl está poco pulido
comparándolo con otros lenguajes. Bueno, es lo que hay.

Al revés, al menos en lo que concierne a lenguajes de script, Perl es de los que mejor lo llevan.

Por ejemplo, Python y Ruby (al menos hasta donde yo sé) solo soportan un modelo similar al de Coro y solo son capaces de utilizar un procesador a la vez.

El problema de fondo es una cuestión de implementación: la representación interna que usan estos lenguajes para los datos (escalares, hashes, arrays, etc.) son estructuras complejas y las operaciones que se realizan sobre ellas distan mucho de ser atómicas a nivel de procesador así que si dos threads tratan de acceder al mismo dato es muy probable que el segundo thread se encuentre la estructura interna del dato en un estado inconsistente y todo acabe en un core dump.

Con la implementación de threads de Perl 5.005 se llegó bastante lejos, pero al final los perl porters llegaron a la conclusión de que nunca conseguirían solucionar todos los problemas y lo discontinuaron tirando por el modelo de 5.6 que a nivel de programación en Perl es un asco, pero que al menos no se cuelga y tiene soporte para multiproceso real.
Avatar de Usuario
salva
Perlero nuevo
Perlero nuevo
 
Mensajes: 200
Registrado: 2008-01-03 15:19 @680


Volver a Avanzado

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 23 invitados