簡體   English   中英

Perl-使用DBD Oracle時文件過多錯誤

[英]Perl - Too many files error when using DBD Oracle

有人可以建議我為什么在下面的代碼中打開文件時出錯。 錯誤開始於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”?

使用線程時,全局變量是...問題,即使不是確切的敵人,也存在很大問題。

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

而且您無需說“使用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;
}

我不了解的一件事-為什么不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子句加載。

嘗試

my $FILE;
open ($FILE, ">/tmp/da") or die "failed $! at iter $j thread $i";
close ($FILE);

這是最佳做法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM