2010-06-22 5 views
2

아래 코드에서 파일을 여는 중 오류가 발생하는 이유에 대해 조언 해 줄 수 있습니까? 오류는 25 번째 스레드의 9 번째 반복 과정의 절반 정도에서 시작되며 "너무 많은 파일 열기"오류가 발생합니다. 이 오류는 스레드에서 실행 중이고 DBI 연결/연결 끊기가 사용되는 경우에만 발생합니다. 열려있는 파일 수에 영향을 미치지 않아야합니까? 나는 Perl에 상당히 익숙하다. 그래서 내가 이상한 짓을했다면 확실하지 않다. 이것은 Perl 5.8.8에 있습니다. 당신이 서브 루틴에서 i와 $에게 $ J를 전역 변수를 사용하고 있는지Perl - DBD를 사용할 때 너무 많은 파일 오류가 발생했습니다.

use warnings; 
use strict; 

이 당신을 말할 것이다 : 솔라리스 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)[email protected]_; 
    open (my $fh, ">/tmp/da") or die "failed $! at iter $x thread $y"; 
    close ($fh); 
    $dbh->disconnect; 
} 
+1

편집기에있는 작은 바이너리 아이콘은 코드를 붙여 넣기위한 것입니다. (마크 업 도움말 가이드를 참조하십시오.) – Ether

+0

나는 그것을 사용했는데 어떤 이유로 작동하지 않았다. 어쨌든, 이제 OK, 감사 –

답변

5

에 당신은 사용해야합니다. 변수에 액세스하는 스레드가 여러 개 있기 때문에 모든 지옥이 느슨해집니다. 또한 그들은 모두 하나의 FILE을 공유하고 있습니다. 또 다른 문제의 원인입니다. 그리고 스칼라 '$ threads'배열과 '@threads'배열을 모두 가지고 있다는 것을 깨달았습니까?

스레드를 사용하면 전역 변수가 ... 정확히는 적은 아니지만 극도로 문제가됩니다.

open의 FILE 핸들 양식을 피하십시오. my을 훨씬 더 자유롭게 사용하십시오.

그리고 'use DBD :: Oracle;'라고 말할 필요는 없습니다. 이제까지. 종종 변형을 사용해야 할 수도 있습니다 :

use DBD::Oracle qw(:ora_types); 

오라클 특정 데이터 유형에 액세스하려면 가끔씩 사용해야 할 수도 있습니다.


안된 수정 : 나는 이해하지 못했다

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;를 사용하지 말아야? 그래서

use DBI; 

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

는 DBD :: 오라클 모듈에 대한 기본 설명서는 사용하지 않는 것을 보여줍니다 당신은 'perldoc을 DBD :: 오라클 보면

, 당신은 시놉시스를 볼 수 있습니다 그것을 직접적으로.

사용시 해를 끼치 지 않습니다. 그것을 사용할 필요가 없습니다. DBI 모듈은 DBI->connect() 호출시 연결 문자열에 포함 된 드라이버를 자동으로로드합니다. use DBD::Oracle;을 쓰면 DBI를 실제로로드하지 않아도됩니다 (이미 완료되었습니다). 모듈이 use 절과 함께로드 될 수 있는지 확인하기 위해 Perl을 얻는다고 가정합니다.

+0

+1. Perl은 발에서 자신을 쏠 수있는 가장 쉬운 언어 중 하나입니다. 도보로 자신을 쏠 수있는 다양한 방법이 있으므로 comp.lang.perl.misc에 쿼리를 게시하여 최적의 방법을 결정하십시오.500 개의 답변 (짧은 Perl 스크립트로 수행)을 통해 선별 한 후, 대부분의 경우 Windows, VMS 및 다양한 기능을 수행하는 동안 리눅스의 모든 맛은 펄 스크립트가 할 수있는 것보다 빨리 발을 쏠 수있게 해준다. ;-) – DCookie

+0

Perl은 프로그래머가 코드를 사용하기로 결정한 경우 발의 총격을 고치는 데 훌륭한 진단 기능을 제공합니다. – Ether

+0

여기에 논쟁이 없습니다! – DCookie

1

이것은 가장 좋은 방법입니다

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

을보십시오.

+0

고마워, 시도했지만, 변경 없음 –