2010-06-07 4 views
2

나는 펄에서 좋은 타이머 구현을 찾고있다. 내가 만난 상황은 다음과 같습니다. 많은 파일의 I/O 활동을 추적해야하고 파일을 삭제할 때 충분한 시간 동안 파일을 유지해야하므로 효과적인 타이머 구현은 앱의 경우 매우 중요합니다. 나는 지금 연루되어있다. 휠을 다시 만들지 않으려면 먼저 도움을 요청하십시오.Perl에 좋은 타이머 구현이 있습니까?

+1

* nix에 있나요? – Zaid

+0

@ Zaid : 예, * nix –

+0

Perl을 사용해야하는 이유가 있습니까? 나는 * nix 명령으로 충분하다고 생각한다. 필요한 경우 백틱과 통합하십시오. – Zaid

답변

6

Time::HiRes은 perl과 함께 제공됩니다.

또한 응용 프로그램이 Linux::Inotify의 이점을 얻을 수있는 것처럼 들리지만 (Linux ::는주의하십시오). 일정 시간 사용하지 않으면 제거 할 파일의 타이머를 설정할 때 마지막 액세스를 기억하십시오. inotify 이벤트 후크에서이 시간을 현재 시간으로 업데이트하십시오. 그런 다음 추적하는 모든 파일에 대해 stat를 수행하지 않고 파일의 수명이 만료되었는지 정기적으로 확인할 수 있습니다. 만료되면, 물론 아무것도 잘못되었는지 확인하기 위해 최종 검사를 추가 할 수 있습니다.

비행 중에 많은 파일이있는 경우 파일 목록을 만료 시간순으로 정렬 할 수 있습니다. 그것은 만료에 대한주기적인 점검을 하찮게 만듭니다.

업데이트 : 저는 Linux :: Inotify에 대한 약간의 실험을했습니다. 내가 생각한 것만 큼 쉽지 않습니다. 첫째, 완성 할 시간이 없었던 부분적으로 작동하는 코드가 있습니다.

#!/usr/bin/env perl 
use strict; 
use warnings; 
use List::Util qw/min max/; 
use Time::HiRes qw/time sleep/; 
use Data::Dumper; 
use Linux::Inotify; 

# [s], but handles subsecond granularity, too 
use constant CLEANUP_INTERVAL => 1.; 
use constant FILE_ACCESS_TIMEOUT => 5.; 

# for fast and readable struct access 
use constant FILENAME => 0; 
use constant ACCESSTIME => 1; 
use constant WATCHER => 2; 

my $notifier = Linux::Inotify->new; 
my @tracked_files = populate_tracked_files(\@ARGV, $notifier); 
warn Dumper \@tracked_files; 

while (1) { 
    # update the tracked files according to inotify events 
    my @events = $notifier->read; 

    my %files_seen_this_round; 
    foreach my $event (@events) { 
    $event->print(); 
    my $ev_filename = $event->{name}; # part of the API, apparently 

    # we mave have multiple events per file. 
    next if $files_seen_this_round{$ev_filename}++; 

    # find and update the right tracked file 
    # TODO: this could be optimized to O(1) with a hash at 
    #  the cost of more bookkeeping 
    foreach my $tfile (@tracked_files) { 
     if ($tfile->[FILENAME] eq $ev_filename) { 
     my $atime = $^T + 60*60*24 * -A $ev_filename; # update access time 
     $tfile->[ACCESSTIME] = $atime; 
     # a partial bubble sort would be hugely more efficient here! 
     # => O(n) from O(n*log(n)) 
     @tracked_files = sort {$a->[ACCESSTIME] <=> $b->[ACCESSTIME]} 
         @tracked_files; 
     last; 
     } 
    } # end foreach tracked file 

    } # end foreach event 

    cleanup_files(\@tracked_files); 

    sleep(CLEANUP_INTERVAL); 

    last if not @tracked_files; 
} # end while(1) 


$notifier->close; 

sub cleanup_files { 
    my $files = shift; 

    my $now = time(); 
    for (my $fileno = 0; $fileno < $#{$files}; ++$fileno) { 
    my $file = $files->[$fileno]; 
    if ($now - $file->[ACCESSTIME] > FILE_ACCESS_TIMEOUT) { 
     warn "File '" . $file->[FILENAME] . "' timed out"; 
     # remove this file from the watch list 
     # (and delete in your scenario) 
     $file->[WATCHER]->remove; 
     splice @$files, $fileno, 1; 
     $fileno--; 
    } 
    } 
} 

sub populate_tracked_files { 
    my $files = shift; 
    my $notifier = shift; 

    my @tracked_files; 
    foreach my $file (@$files) { 
    die "Not a file: '$file'" if not -f $file; 

    my $watch = $notifier->add_watch($file, Linux::Inotify::ALL_EVENTS); 
    push @tracked_files, [$file, $^T + 60*60*24*-A $file, $watch]; 
    } 
    @tracked_files = sort {$a->[ACCESSTIME] <=> $b->[ACCESSTIME]} 
        @tracked_files; 

    return @tracked_files; 
} 

시간 확인 논리에는 여전히 버그가 있습니다. 그러나 주된 문제는 $notifier->read()이 새로운 이벤트가 발생할 때까지 차단된다는 것입니다. 반면에 새로운 사건이 있는지 확인한 다음 정리 작업을 진행하기 만하면됩니다. 이것은 Linux :: Inotify에 파일 디스크립터의 non-blocking 읽기로 추가되어야한다. 누구든지 the author is no longer interested 이후 모듈 유지 관리를 대신 할 수 있습니다.

+0

리눅스 :: Inotify2는 "리눅스보다 많은 이점을 가지고 있습니다 : : Inotify 모듈 :" –

+0

아담 : 정말로, 나는 그것을 놓쳤습니다. 부끄러운 줄 알아. 또한 Marc Lehmann 모듈 (예 : Linux :: Inotify2)은 일반적으로 높은 품질을 제공합니다. – tsee

+1

['File :: ChangeNotify'는 크로스 플랫폼에서 작동합니다.] (http://stackoverflow.com/questions/1776745#1778606); 'Linux :: Inotify2'도 사용합니다. – daxim

3

프로그램이 명확하게 이벤트 중심으로 보이는 경우 POE 또는 AnyEvent와 같은 이벤트 중심 프레임 워크를 사용하여 프로그램을 구현하면 도움이됩니다. 그것들은 I/O 이벤트와 타이머 이벤트를 처리하기위한 모든 부분을 가지고 있습니다.

관련 문제