2010-06-27 7 views
4

Je suis intéressé à effectuer plusieurs actions de base de données en parallèle. J'ai joué avec Perl Parallel :: ForkManager mais je ne l'ai pas encore utilisé avec des bases de données. J'ai lu que la connectivité de base de données est not supported very well avec ceci. Est-ce que quelqu'un a de l'expérience avec ça?Perl Parallel :: ForkManager avec les gestionnaires de base de données DBI

À titre d'exemple je serais probablement frai un appel système (qui fait le travail de DBI) NOT code brut, à savoir

#!/opt/local/bin/perl -w 

use strict; 
use Parallel::ForkManager; 

$| = 1; 

my $max_procs = 10; 

my $pm = new Parallel::ForkManager($max_procs); 

for (my $var = 0; $var <= 10; $var++) { 
    my $pid = $pm->start('proc'.$var) and next; 
    sleep (2); 
    system("./DBworker.pl $var"); 
    $pm->finish(0); 
} 

print "Waiting for child procs\n"; 
$pm->wait_all_children; 
print "complete!\n"; 

Répondre

7

Si le travail est effectué par d'autres programmes, il n'y a aucun danger pour fork ing. Le danger vient lorsque vous ouvrez une connexion à la base de données, puis bifurquez. L'enfant ne peut pas réutiliser la connexion des parents; Cependant, jetez un oeil à DBIx::Connector, il gère les choses que vous devez faire après fork ing pour vous et l'exécution de plusieurs programmes n'est généralement pas la bonne réponse.

#!/usr/bin/perl 

use strict; 
use warnings; 

use DBIx::Connector; 
use Parallel::ForkManager; 

my $dsn = "dbi:SQLite:dbname=foo.db"; 
my $user = ""; 
my $pass = ""; 
my $conn = DBIx::Connector->new($dsn, $user, $pass, 
    { 
     AutoCommit  => 0, 
     PrintError  => 0, 
     RaiseError  => 1, 
     ChopBlanks  => 1, 
     FetchHashKeyName => 'NAME_lc', 
    } 
); 
END { unlink "foo.db" } 

#setup table 
$conn->run(fixup => sub { 
    my $dbh = $_; 
    $dbh->do("create table foo (id integer, name char(35))"); 
    my $sth = $dbh->prepare("insert into foo (id, name) values (?, ?)"); 
    while (<DATA>) { 
     chomp; 
     $sth->execute(split /,/); 
    } 
}); 

my $pm = Parallel::ForkManager->new(3); 

my $sth = $conn->dbh->prepare("select * from foo where id = ?"); 
for my $id (1 .. 3) { 
    next if $pm->start; 
    $sth->execute($id); 
    while (my $row = $sth->fetchrow_hashref) { 
     print "$id saw $row->{id} => $row->{name}\n"; 
    } 
    $pm->finish; 
} 

$pm->wait_all_children; 

print "done\n"; 

__DATA__ 
1,foo 
2,bar 
3,baz 
+0

Ce script est-il supposé fonctionner sous Windows? – MeirG

+0

@MeirG puisque Windows ne supporte pas nativement fork (il est émulé avec quelques différences), je ne peux pas le dire avec certitude. Je n'ai pas de machine Windows à tester, mais si vous rencontrez des problèmes, signalez simplement ce qui ne va pas comme une nouvelle question. –

Questions connexes