Perl - 使用 DBD Oracle 时出现文件过多错误

标签 perl oracle dbd

有人可以告诉我为什么在下面的代码中打开文件时出错。这些错误大约在 25 个线程的第 9 次迭代进行到一半时开始出现,并且是“打开文件过多”错误。该错误仅在线程中运行时发生,并且仅在使用 DBI 连接/断开连接时发生。这根本不会影响打开文件计数,不是吗? 我对 Perl 相当陌生,所以不确定我是否做了一些奇怪的事情。这是 Perl 5.8.8 上的。在 Solaris 10 上。

use threads ();
use DBI;
use DBD::Oracle;

my $thrds=25;
my $iter=10;
my @threads;

for (my $j=0; $j<$iter; $j++) {
    &start($j);
}

sub start {
    my $k=$_[0];
    for (my $i=0; $i<$thrds; $i++) {
        $threads[$i] = threads->new(\&RunThread,$k, $i);
    }
    for (my $i=0; $i<$thrds; $i++) { $threads[$i]->join; }
}

sub RunThread {
    my $dbh = DBI->connect("dbi:Oracle:lnrmsd9.world", "rms_reader", "rms_reader") or die "failed connect";
    my ($x, $y)=@_;
    open (my $fh, ">/tmp/da") or die "failed $! at iter $x thread $y";
    close ($fh);
    $dbh->disconnect;
}

最佳答案

您需要使用:

use warnings;
use strict;

这些会告诉您您正在子例程中使用全局变量 $i 和 $j。由于您有多个线程访问变量,所以一切都变得困惑了。此外,它们也都共享一个文件——这是另一个麻烦来源。您是否意识到您同时拥有标量“$threads”和数组“@threads”?

对于线程,全局变量......好吧,即使不是完全的敌人,也是非常有问题的。

避免使用open的FILE句柄形式;更自由地使用my

你不需要说“use DBD::Oracle;”曾经。您有时可能需要使用变体:

use DBD::Oracle qw( :ora_types );

访问 Oracle 特定的数据类型。


未经测试的修订版:

use strict;
use warnings;
use threads ();
use DBI;
use DBD::Oracle;

my $threads=25;
my $iter=10;

for ($j = 0; $j < $iter; $j++) {
    &start($j);
}

sub start {
    my($j) = @_;
    my(@threads);
    for (my $i = 0; $i < $threads; $i++) {
        $threads[$i] = threads->new(\&RunThread,$j, $i);
    }
    for ($i=0; $i < $threads; $i++) { $threads[$i]->join; }
}

sub RunThread {
    my $dbh = DBI->connect("dbi:Oracle:ora", "user", "pass") or die "failed connect";
    my($j, $i) = @_;
    open(my $fh, ">/tmp/da") or die "failed $! at iter $j thread $i";
    close $fh;
    $dbh->disconnect;
}

One thing I didn't understand - why shouldn't I use use DBD::Oracle;?

如果您查看“perldoc DBD::Oracle”,您将看到概要:

use DBI;

$dbh = DBI->connect("dbi:Oracle:$dbname", $user, $passwd);

因此,DBD::Oracle 模块的主要文档表明您没有直接使用它。

使用它没有任何害处;没有必要使用它。 DBI 模块自动加载 DBI->connect() 调用中的连接字符串所隐含的驱动程序。通过编写 use DBD::Oracle;,您可以使 DBI 不必实际执行加载(它已经完成)。我想您还让 Perl 来验证该模块是否可以使用 use 子句加载。

关于Perl - 使用 DBD Oracle 时出现文件过多错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3094154/

相关文章:

oracle - 同一个表上的两个相同类型的触发器将首先执行?

sql - 如何更新循环中 SELECT 返回的行?

linux - 传递其中包含点运算符的命令行参数

linux - shell 脚本内的 perl -p -i -e

perl - Perl LWP POST 上传的进度指示器

mysql - 从 Oracle VARCHAR2 转换为 MySQL TEXT

sql - Oracle SQL 获取两个特殊字符之间的值

perl - Perl 是繁重文本处理的好选择吗?

mysql - 安装: missing destination file operand after `PREFIX=~/perlmods'

perl - 基于Sqlite的DBI::CSV实现