2009-07-28 8 views
5

Lo he intentado con Perl fork manager y DBI. Pero recibí el error DBD :: mysql :: st execute failed: Perdí la conexión con el servidor MySQL durante la consulta.¿Por qué no puedo consultar una base de datos de un niño bifurcado en Perl?

Aquí el código de ejemplo: Quiero hacer consultas entre menor a mayor valor (he escupido registros int 10k)

use Parallel::ForkManager; 
my $pm = new Parallel::ForkManager(50); 
my $db = krish::DB->new or die $!; # its has all connection details 
while ($low < $high ) { 
    # Some value manipulation 

    my $pid = $pm->start and next; 
    #db_execution returns execution 
    while (my $sth = db_execution ($db, $low , $high)) { 
     ... 
     #fetch row operation 
     ... 
    } 
    $pm->finish; 
} 

sub db_execution { 
    ... 
    my $dbh = $db->connect('students') or die $!; 
    my $sth = $dbh->prepare($sql) or die "$!:" . $dbh->errstr; 
    $sth->execute or die "$!:" . $sth->errstr; 
    ... 
} 

El mismo código se ejecuta con el procesamiento en paralelo a cabo. ¿Cual es el problema? ¿Cómo resolver esto?

+0

Lo siento todos. Me he convertido erróneamente en wiki de la comunidad – joe

Respuesta

9

Cuando comparte conexiones de bases de datos entre procesos (que es lo que está haciendo con un fork) necesita asegurarse de que un proceso no lo cierre por debajo del otro. Debido a que las conexiones también son variables, cuando el intérprete de Perl se apaga llamará al método DESTROY de ese objeto que en este caso cerrará la conexión.

De modo que si alguno de los niños cierra la conexión db (lo que ocurrirá cuando finalicen y cierren) lo eliminará del proceso principal. La forma de evitar esto es establecer InactiveDestroy en true en el proceso principal antes de la bifurcación y luego cerrar la conexión explícitamente en el elemento primario cuando finalice.

https://metacpan.org/pod/DBI#InactiveDestroy

+3

Otra forma de hacerlo es simplemente abrir la conexión de la base de datos después de 'fork()'. De esta forma, cada niño tiene su propia conexión y no pueden interferir entre sí. Compartir una única conexión entre múltiples procesos no suele ser una buena idea. –

+1

Sí, eso también funciona. Especialmente dado que algunos sistemas (como Oracle) no admiten la conexión compartida entre procesos. – mpeters

0

Usted está buscando problemas usando el mismo mango db de forma simultánea en todos los procesos hijos. Debería estar creando una nueva conexión en cada niño.

No importa ... He leído el resto del código.

Cuestiones relacionadas