2009-11-18 3 views
2

저는 epoll 기반 이벤트 루프를 사용하여 여러 개의 동시 소켓 연결을 처리하는 프로그램을 만들고 있습니다. 앱이 읽을 데이터가 있음을 감지하면 버퍼링 된 IO를 사용하는 process_request() 하위를 호출합니다. 예를 들어 :Perl의 입력 파일 핸들 버퍼에 데이터가 있는지 어떻게 알 수 있습니까?

sub process_request { 
    my ($fh) = @_; 
    if (my $line = <$fh>) { 
     # Do something interesting 
    } 
} 

문제는 여기에 I/O를 버퍼 사용하여이 process_request()를 다시 호출하지 않습니다, 그래서는 epoll은, 버퍼에 대기 읽지 않은 데이터가 있다는 것을 알고하지 않습니다.

Perl의 파일 핸들에 읽지 않은 데이터가 있는지 어떻게 확인할 수 있습니까? 그래서 데이터가 버퍼에 남아있는 한 process_request()를 다시 호출 할 수 있습니까?

+0

잘못된 대답을 취소했습니다. 여기에서 중요한 점은 버퍼에 아무것도 남아 있지 않을 때 <$fh> 처리를 중지하고 나중에 더 많은 데이터가 버퍼에 도착할 것으로 예상하고 기다리지 않고 다른 작업을 수행하려는 경우입니다. –

답변

1

음, 나는 POE가 아니라 자신 만의 이벤트 루프를 사용하고 있지만 POE의 필터를 빌려야 할 수도 있습니다. POE의 나머지 부분을 사용하지 않고로드 할 수 있습니다. 소켓 당 POE::Filter::Line을 초기화하고 소켓이 읽을 수있게되면 비 블로킹 read을 수행하고 $filter->get으로 필터에 푸시합니다. 리턴은 (0 개 또는 그 이상의) 행들의 배열 참조가 될 것이고, 모든 부분 라인들은 나머지 라인을 기다리는 필터에 저장 될 것이다.

그게 매력적이지 않다면, 당신은 언제나 같은 생각을 직접 구현할 수 있습니다. 엄청난 양의 작업이 아니라 소켓 당 문자열 버퍼와 정규 표현식을 사용합니다.

+0

그러면 API 계약이 변경되지만, Tie :: Handle과 함께하면 필요한 항목을 얻을 수 있습니다. – Flimzy

+0

나는 그 데이터를 잠재적으로 필터에 삼켜 버릴 수없는 다른 것과 핸들을 공유해야한다는 문제가 있다고 가정하고 있습니까? 일하는 방식의 중요한 변경 사항은 데이터가 소켓의 필터 대신 버퍼의 버퍼에 남아 있기 때문입니다. 그렇다면 제대로 된 것 같습니다.하지만 추한 넥타이 인터페이스 라기보다는 오브젝트 (IO :: Handle 또는 IO :: Socket을 서브 클래 싱하는 것)를 사용할 수 있습니다. :) – hobbs

관련 문제