2011-08-05 3 views
1

파일 핸들을 포함하는 해시 참조를 설정 중입니다.Perl에서 열 수있는 파일 핸들 수에 제한이 있습니까?

$ cut -f4 myFile | sort | uniq 
id-0001 
id-0002 
... 
: 나는 식별자의 목록을 얻으려면 GNU 기본 유틸리티를 사용

col1 col2 col3 id-0008 col5 
col1 col2 col3 id-0002 col5 
col1 col2 col3 id-0001 col5 
col1 col2 col3 id-0001 col5 
col1 col2 col3 id-0007 col5 
... 
col1 col2 col3 id-0003 col5 

:

내 입력 파일의 네 번째 열은 내가 파일 핸들의 목적지 이름을 사용하고 식별자 필드를 포함

이 열에 1024 개가 넘는 고유 식별자가있을 수 있으며 각 식별자에 대해 파일 핸들을 열고 해당 핸들을 해시 참조에 넣어야합니다. 펄의 상한은 해시 참조 I 열 수있는 파일 핸들 또는 저장소의 수에 거기에

opening handle to: /foo/bar/baz/id-0001/coordinates.bed 
opening handle to: /foo/bar/baz/id-0002/coordinates.bed 
... 
opening handle to: /foo/bar/baz/id-1022/coordinates.bed 
could not open handle to /foo/bar/baz/id-1022/coordinates.bed 
0 
6144 at ./process.pl line 66. 

:

my $fhsRef; 
my $fileOfInterest = "/foo/bar/fileOfInterest.txt"; 

openFileHandles($fileOfInterest); 
closeFileHandles(); 

sub openFileHandles {                                                    
    my ($fn) = @_;                                                    

    print STDERR "getting set names... (this may take a few moments)\n";                                       
    my $resultStr = `cut -f4 $fn | sort | uniq`;                                         
    chomp($resultStr);                                                    
    my @setNames = split("\n", $resultStr);                                               

    foreach my $setName (@setNames) {                                                
     my $destDir = "$rootDir/$subDir/$setName"; if (! -d $destDir) { mkpath $destDir; }                                   
     my $destFn = "$destDir/coordinates.bed";                                             
     local *FILE;                                                    
     print STDERR "opening handle to: $destFn\n";                                            
     open (FILE, "> $destFn") or die "could not open handle to $destFn\n$!\n";                                     
     $fhsRef->{$setName}->{fh} = *FILE;                                               
     $fhsRef->{$setName}->{fn} = $destFn;                                              
    }                                                        
}                                                         

sub closeFileHandles {                                                    
    foreach my $setName (keys %{$fhsRef}) {                                               
     print STDERR "closing handle to: ".$fhsRef->{$setName}->{fn}."\n";                                       
     close $fhsRef->{$setName}->{fh};                                               
    }                                                        
}  

문제는 내 코드 id-1022의 동등한에서 죽어 가고 있다는 것입니다 ? 아니면 다른 곳에서 다른 실수를 저질렀습니까?

+2

Perl은 제한을 두지 않지만 사용자의 OS는 확실하게 않습니다. (1024, STDIN + STDOUT + STDERR + 1021) 제한은 구성 가능할 수 있습니다. 그건 그렇고,'$!'이 아니라'$!'를 출력해야합니다. – ikegami

+0

네 말이 맞아, 오타. –

+2

http://perldoc.perl.org/FileCache.html FileCache는 열린 파일에 대한 OS 제한을 초과 할 수 있도록하는 표준 모듈입니다. – d5e5

답변

6

모든 프로그래밍 언어에서 프로세스 당 열린 파일 수에는 제한이 있습니다.

실제로는 운영 체제가 악의적 인 (또는 가짜) 프로그램이 시스템의 모든 리소스를 사용하지 못하도록 제한함으로써 운영 체제가 정지 될 수 있습니다.

Linux 기반 (Mac이 아닌) OS를 사용하는 경우 ulimit/etc/security/limits.conf을 확인하십시오.

ulimit -n 2048 

이것은 대부분의 Linux 배포판에서 작동합니다.

Mac 용 구성 (이 특정 지점에서는 유닉스와 다릅니다) 및/또는 Windows를 모르겠습니다.


편집 :

제한 운영 체제의 OS의 X가 launchctl 도구를 사용하여 정의됩니다

launchctl limit maxfiles 2048 unlimited 
+0

'ulimit -n 2048'을 실행하는 것이 트릭입니다. 매우 감사합니다! –

+0

이런 종류의 속임수를 쓰기 전에 수천 개의 파일을 동시에 열어 볼 필요가 있는지 생각해보십시오. –

+0

열기 및 닫기 파일 핸들에 시간이 필요합니다. 모든 핸들을 동시에 열어 둘 수 있다면 제한을 초과하지 않기 위해 계속 열고 닫는 작은 핸들 풀을 관리하기 위해 코드를 작성하고 디버깅 할 필요가 없습니다. –

5

OS에 부과 된 제한이 있습니다. stdin/stdout/stderr는 모두 FD로 간주됩니다. Linux의 기본 FD 제한은 프로세스 당 1024입니다. This question은 약간 자세한 정보를 제공합니다.

내가 사용했던 대부분의 리눅스에 대한 하드 제한은 1024입니다. /etc/security/limits.conf (경로는 배포판에 따라 다를 수 있음)을 확인하여 늘릴 수 있는지 확인하십시오.

또한 이러한 파일을 모두 한 번에 열 필요가 없도록 스크립트를 다시 작성하는 것이 좋습니다. 모든 데이터를로드하거나 지연로드 메커니즘을 제공하여 필요할 때 데이터를로드 한 다음 파일을 닫습니다.

+0

저는 메모리에 들어갈 수있는 것보다 큰 파일 크기로 작업하고 있습니다. 아이디어는 한 번에 한 줄씩 파일을 스트리밍하여 훨씬 작은 파일의 큰 세트로 나눕니다. 핸들 풀을 열어두면 큰 파일의 각 줄을 처리 할 때마다 각자 빨리 쓸 수 있습니다. –

관련 문제