• Publicidad

Mismo manejador de archivo con distintos hilos

¿Eres administrador de sistemas? Este foro es para todos aquellos temas relacionados con el uso de Perl para administración de sistemas.

Mismo manejador de archivo con distintos hilos

Notapor estudiante » 2015-04-10 09:16 @427

Hola, ¿hay alguna manera de que desde distintos hilos puedan escribir en el mismo fichero sin sobrescribir información ya escrita?

Un saludo y gracias.
estudiante
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2013-02-06 07:36 @358

Publicidad

Re: Mismo manejador de archivo con distintos hilos

Notapor explorer » 2015-04-10 12:08 @547

Hay módulos, como Sys::Mmap, que permite compartir los contenidos de un archivo entre varios hilos.

Otra cosa es escribir un archivo de registro, un log. ¿Es ese el caso?
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: Mismo manejador de archivo con distintos hilos

Notapor estudiante » 2015-04-10 14:30 @646

Hola, explorer, efectivamente estoy intentando que varios hilos escriban en un fichero que es un log.

¿No hay alguna manera de compartir el descriptor de fichero entre los distintos hilos al igual que se hace con las variables?

Otra duda que tengo, es si da problemas abrir el mismo fichero siempre en lectura con distintos descriptores de ficheros y pasar a cada hilo un descriptor diferente (como yo lo entiendo cada vez que creo un descriptor apunta a la primera línea del fichero y mientras solo abra el fichero del mismo modo, no debería de dar problema).

Un saludo.
estudiante
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2013-02-06 07:36 @358

Re: Mismo manejador de archivo con distintos hilos

Notapor explorer » 2015-04-10 16:52 @744

Bueno, la forma moderna de abrir un archivo es así:

open my $HANDLE, '>>', 'archivo.log';

Así que ya ves que el gestor de archivo es una variable. Y por lo tanto, la puedes compartir entre los distintos hilos.

Ahora bien... es muy posible que varios hilos intenten escribir a la vez. Mientras un hilo está escribiendo algo, en ese momento puede entrar en la CPU el contexto de otro hilo, que escribirá su correspondiente salida. Luego regresa al primero hilo, que escribirá el resto. Así que la salida queda mezclada.

Habría que usar un sistema de bloqueo en el acceso, o un sistema parecido a lo que usan programas como Apache, que permiten que varios hilos accedan a los mismos registros (la verdad, no sé cómo lo hacen, creo que tiene que ver con tuberías -pipes-, pero no lo he mirado).

Si abres el mismo archivo pero con descriptores diferentes, cada descriptor guardará un puntero de posicionamiento de escritura diferente, por lo que la salida de un hilo quedará sobrescrito por la salida de los demás.

El asunto es complejo, sin duda. La clave está en lo siguiente: en los sistemas UNIX es casi imposible realizar una operación de escritura en un archivo, de forma simultánea, sin corromper el propio archivo.

Hay varias opciones. Por ejemplo: cuando un hilo quiere escribir en el registro, primero lo bloquea (lock()), luego hace un seek() para posicionarse al final del registro, escribe la salida, y termina desbloqueando el acceso. Ejemplo:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. sub proceso {  
  2.    lock(\*LOG);                 # bloquear
  3.    print LOG "lo-que-sea...";   # pintar
  4.    unlock(\*LOG);               # desbloquear
  5. }
  6.  
  7. use Fcntl qw(:flock SEEK_END);
  8.  
  9. sub lock {
  10.   my ($fh) = @_;                        # recibimos el descriptor de archivo
  11.   flock($fh, LOCK_EX) or die $!;        # solicitamos el bloqueo, y de forma esclusiva
  12.   seek($fh, 0, SEEK_END) or die $!;     # nos colocamos al final del archivo
  13. }
  14.  
  15. sub unlock {
  16.   my ($fh) = @_;
  17.   flock($fh, LOCK_UN) or die $!;        # desbloqueamos el acceso
  18. }
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


Hay soluciones más elaboradas, como la de que ir creando espacio (un relleno de ceros) justo antes de escribir la propia línea, en el registro.

En este hilo de blogs.perl.org se comenta el mismo problema: Suprisingly hard task of writing logs. Y también se comentan diversas soluciones.
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: Mismo manejador de archivo con distintos hilos

Notapor estudiante » 2015-04-11 14:44 @655

Gracias de nuevo, explorer, probaré con tu código. Otra idea podría ser escribir en distintos ficheros y luego juntarlos en uno solo.

Otra pregunta, si hiciera lo siguiente:

open(MANEJADOR1,"<$fichero");
open(MANEJADOR2,"<$fichero");
open(MANEJADOR3,"<$fichero");
open(MANEJADOR4,"<$fichero");
open(MANEJADOR5,"<$fichero");

y que después, cada manejador fuera en un hilo para ir leyendo cada uno por su lado el fichero. ¿Puede dar problemas?

Un saludo.
estudiante
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2013-02-06 07:36 @358

Re: Mismo manejador de archivo con distintos hilos

Notapor explorer » 2015-04-13 10:03 @460

Si el tema es leer de un archivo, ni siquiera te haría falta crear tantos manejadores de archivo. Con uno sería suficiente(*).

El problema está a la hora de escribir.


(*) excepto en Windows, naturalmente.
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: Mismo manejador de archivo con distintos hilos

Notapor estudiante » 2015-04-16 04:32 @231

Gracias, explorer. Como siempre un 10 :)
estudiante
Perlero nuevo
Perlero nuevo
 
Mensajes: 9
Registrado: 2013-02-06 07:36 @358


Volver a Administración

¿Quién está conectado?

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