【问题标题】:Perl Parallel::ForkManager with DBI database handlersPerl Parallel::ForkManager 与 DBI 数据库处理程序
【发布时间】:2010-06-27 11:40:14
【问题描述】:

我对并行执行多个数据库操作很感兴趣。我玩过 Perl Parallel::ForkManager 但还没有在任何数据库中使用它。我已经读到数据库连接是not supported very well。有人有这方面的经验吗?

作为一个例子,我可能会产生一个系统调用(它执行 DBI 工作)而不是原始代码,即

#!/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";

【问题讨论】:

    标签: perl dbi parallel-processing


    【解决方案1】:

    如果工作由其他程序完成,forking 没有危险。当您打开与数据库的连接然后分叉时,危险就来了。孩子不能重用父母连接;但是,看看DBIx::Connector,它会为您处理forking 之后您需要做的事情,并且运行多个程序通常不是正确的答案。

    #!/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
    

    【讨论】:

    • 这个脚本也应该在 Windows 上运行吗?
    • @MeirG 因为 Windows 本身不支持 fork(它被模拟了一些差异),我不能肯定地说。我没有要测试的 Windows 机器,但如果您遇到任何问题,只需将问题所在作为新问题发布即可。
    猜你喜欢
    • 1970-01-01
    • 2011-01-26
    • 2013-04-16
    • 1970-01-01
    • 2017-06-24
    • 2017-03-14
    • 1970-01-01
    • 2018-12-09
    • 1970-01-01
    相关资源
    最近更新 更多