2010-05-11 28 views
5

He escrito los dos programas. Un programa es escribir el contenido en el archivo de texto simultáneamente. Otro programa es leer ese contenido simultáneamente.Leer y escribir en el mismo archivo con proceso diferente

Pero ambos programas deberían ejecutarse al mismo tiempo. Para mí el programa es escribir el archivo es correcto. Pero otro programa no se lee el archivo.

Sé que una vez que se completa el proceso de escritura, solo los datos se almacenarán en el disco duro. Luego, otro proceso puede leer los datos.

Pero quiero leer y escribir al mismo tiempo con diferentes procesos en el archivo único. ¿Cómo puedo hacer eso?

Por favor, ayúdame. El siguiente código escribir el contenido en el archivo

sub generate_random_string 
{ 
    my $length_of_randomstring=shift;# the length of 
     # the random string to generate 

    my @chars=('a'..'z','A'..'Z','0'..'9','_'); 
    my $random_string; 
    foreach (1..$length_of_randomstring) 
    { 
     # rand @chars will generate a random 
     # number between 0 and scalar @chars 
     $random_string.=$chars[rand @chars]; 
    } 
    return $random_string; 
} 
#Generate the random string 
open (FH,">>file.txt")or die "Can't Open"; 
while(1) 
{ 
my $random_string=&generate_random_string(20); 
sleep(1); 
#print $random_string."\n"; 
print FH $random_string."\n"; 
} 

El siguiente código se lee el contenido. Este es otro proceso

open (FH,"<file.txt") or die "Can't Open"; 
       print "Open the file Successfully\n\n"; 
       while(<FH>) 
       { 
        print "$_\n"; 
       } 
+1

Lo que has intentado todavía. ¿Puedes compartir el código que has probado? – Space

+0

Intente leer el archivo Modo NO BLOQUEAR – sganesh

+0

Es posible que desee cerrar el archivo en el programa de escritura antes de abrirlo en el programa de lectura. ¿Y cómo se asegura de que la lectura solo suceda después de una escritura? – AngryWhenHungry

Respuesta

-1

¿Está usted en Windows o * nix? es posible que pueda enhebrar algo como esto en * nix usando cola para obtener el resultado tal como está escrito en el archivo. En Windows, puede llamar a CreateFile() con FILE_SHARE_READ y/o FILE_SHARE_WRITE para permitir que otros accedan al archivo mientras lo tiene abierto para lectura/escritura. es posible que tenga que comprobar periódicamente si el tamaño del archivo ha cambiado para saber cuándo leer (no estoy 100% seguro aquí)

otra opción es un archivo mapeado en la memoria.

3

Esto funciona.

El escritor:

use IO::File(); 

sub generate_random_string {...}; # same as above 

my $file_name = 'file.txt'; 
my $handle = IO::File->new($file_name, 'a'); 
die "Could not append to $file_name: $!" unless $handle; 
$handle->autoflush(1); 

while (1) { 
    $handle->say(generate_random_string(20)); 
} 

El lector:

use IO::File qw(); 

my $file_name = 'file.txt'; 
my $handle = IO::File->new($file_name, 'r'); 
die "Could not read $file_name: $!" unless $handle; 

STDOUT->autoflush(1); 
while (defined (my $line = $handle->getline)) { 
    STDOUT->print($line); 
} 
4

Usted puede utilizar un protocolo de cooperación elaborado como en la siguiente. Ambos extremos, reader y writer, usan un código común en el módulo TakeTurns que maneja detalles molestos como el bloqueo y dónde vive el archivo de bloqueo. Los clientes solo necesitan especificar lo que quieren hacer cuando tienen acceso exclusivo al archivo.

lector

#! /usr/bin/perl 

use warnings; 
use strict; 

use TakeTurns; 

my $runs = 0; 
reader "file.txt" => 
     sub { 
     my($fh) = @_; 
     my @lines = <$fh>; 
     print map "got: $_", @lines; 
     ++$runs <= 10; 
     }; 

escritor

#! /usr/bin/perl 

use warnings; 
use strict; 

use TakeTurns; 

my $n = 10; 
my @chars = ('a'..'z','A'..'Z','0'..'9','_'); 

writer "file.txt" => 
     sub { my($fh) = @_; 
      print $fh join("" => map $chars[rand @chars], 1..$n), "\n" 
       or warn "$0: print: $!"; 
      }; 

El módulo TakeTurns es execute-around en el trabajo:

package TakeTurns;        

use warnings;          
use strict;          

use Exporter 'import';       
use Fcntl qw/ :DEFAULT :flock /;     

our @EXPORT = qw/ reader writer /;    
my $LOCKFILE = "/tmp/taketurns.lock";    

sub _loop ($&) { 
    my($path,$action) = @_; 
    while (1) { 
    sysopen my $lock, $LOCKFILE, O_RDWR|O_CREAT 
            or die "sysopen: $!"; 
    flock $lock, LOCK_EX   or die "flock: $!"; 
    my $continue = $action->(); 
    close $lock     or die "close: $!"; 
    return unless $continue; 
    sleep 0; 
    } 
} 

sub writer { 
    my($path,$w) = @_; 
    _loop $path => 
     sub { 
      open my $fh, ">", $path or die "open $path: $!"; 
      my $continue = $w->($fh); 
      close $fh     or die "close $path: $!"; 
      $continue; 
     }; 
} 

sub reader { 
    my($path,$r) = @_; 
    _loop $path => 
     sub { 
      open my $fh, "<", $path  or die "open $path: $!"; 
      my $continue = $r->($fh); 
      close $fh      or die "close $path: $!"; 
      $continue; 
     }; 
} 

1; 

de salida de la muestra:

got: 1Upem0iSfY 
got: qAALqegWS5 
got: 88RayL3XZw 
got: NRB7POLdu6 
got: IfqC8XeWN6 
got: mgeA6sNEpY 
got: 2TeiF5sDqy 
got: S2ksYEkXsJ 
got: zToPYkGPJ5 
got: 6VXu6ut1Tq 
got: ex0wYvp9Y8

Aunque se haya tomado tantas molestias, todavía hay problemas. El protocolo no es confiable, por lo que reader no tiene garantía de ver todos los mensajes que envía writer. Sin writer activo, reader se contenta con leer el mismo mensaje una y otra vez.

Puede agregar todo esto, pero un enfoque más sensato sería utilizar las abstracciones que ya proporciona el sistema operativo.

Por ejemplo, Unix named pipes parece ser un bonito partido cercano a lo que quiere, y tenga en cuenta lo sencillo que el código es:

pread

#! /usr/bin/perl 

use warnings; 
use strict; 

my $pipe = "/tmp/mypipe"; 
system "mknod $pipe p 2>/dev/null"; 

open my $fh, "<", $pipe or die "$0: open $pipe: $!"; 

while (<$fh>) { 
    print "got: $_"; 
    sleep 0; 
} 

pwrite

#! /usr/bin/perl 

use warnings; 
use strict; 

my $pipe = "/tmp/mypipe"; 
system "mknod $pipe p 2>/dev/null"; 

open my $fh, ">", $pipe or die "$0: open $pipe: $!"; 

my $n = 10; 
my @chars = ('a'..'z','A'..'Z','0'..'9','_'); 

while (1) { 
    print $fh join("" => map $chars[rand @chars], 1..$n), "\n" 
    or warn "$0: print: $!"; 
} 

Ambos extremos intentan crear la tubería usando mknod porque no tienen otro método de sincronización. Al menos uno fallará, pero no nos importa mientras exista la tubería.

Como puede ver, el sistema maneja toda la maquinaria en espera, por lo que hace lo que le importa: leer y escribir mensajes.

Cuestiones relacionadas