2012-09-28 4 views
4

O_ASYNC 옵션을 사용하고 파이프를 읽을 수있을 때 SIGIO 처리기가 실행됩니다.perl에서 O_ASYNC 및 fcntl을 사용하는 방법은 무엇입니까?

하지만 다음 코드는 작동하지 않습니다. 어느 누구도 나를 도울 수 있습니까?

#!/bin/env perl 
use Fcntl; 
$SIG{IO}= sub { 
    print "catch SIGIO!\n"; 
}; 

my $flags=0; 

open(FH,"-|","sleep 4 ;echo aaa") or die "$!"; 

fcntl(FH,F_GETFL,$flags) or die "$!"; 
fcntl(FH,F_SETFL,$flags | O_NONBLOCK | O_ASYNC) or die "$!"; 

sleep(5); 

print "complete\n"; 

내 펄 버전은 5.16.1입니다, 운영 시스템 레드햇 5u4, 커널 2.6.18, x86_64에있다

+0

FIFO에서 O_ASYNC는 C에서 시스템에서 작동합니까? – pilcrow

+0

C 버전을 작성했지만 작동하지 않았습니다. C 예제를 줄 수 있습니까? – Chinaxing

답변

4

리눅스에서, 당신이 모두 요청 비동기 알림 (O_ASYNC)과받는 사람을 지정해야합니다 (F_SETOWN) .

#!/bin/env perl 

use Fcntl; 

$SIG{IO}= sub { 
    print "catch SIGIO!\n"; 
}; 

my $flags=0; 

open(FH,"-|","sleep 4 ;echo aaa") or die "$!"; 

fcntl(FH,F_GETFL,$flags) or die "$!"; 
fcntl(FH,F_SETFL,$flags | O_NONBLOCK | O_ASYNC) or die "$!"; 
fcntl(FH,F_SETOWN,0 + $$) or die "$!"; # <-- Note that we force $$ to be numeric 

sleep(5); 

print "complete\n"; 

을 위의 실행 :

$ perl so-12640993.pl 
catch SIGIO! 
complete 
+0

일반적인 파이프가 열리는 대신 fancy''- | ''인수를 사용하는 이유는 무엇입니까? nummifying'$$'에 좋은 캐치, BTW. – tchrist

+0

@tchrist, re :' "- |"', 그냥 OP의 허구를 복사. Re :'0 + $$', 고마워. – pilcrow

+0

파일의 기본 소유자는 누구입니까? 그것을 여는 과정이 아닌가? – Chinaxing

1

SIGIO 기반 비동기 IO가 트리거 수평을 이루지 에지 트리거 그래서, 당신은 그것을 작동하게하기 위해 예를 하나의 줄을 추가하기 만하면됩니다.

어떤 파일 핸들을 보내기 전에 SIGIO을 먼저 보내야합니다. 이를 수행하려면 sysread()과 같은 작업을 수행해야합니다 (undef/EAGAIN). 이 시점에서 파일 핸들은 SIGIO에 대해 활성화되고 다음에 읽기 준비가되면 신호를 보냅니다. EAGAIN이 나올 때까지 읽을 수 있습니다. 그러면 다시 한 번 움직입니다.

+0

이 분석은 착각입니다. 내가''(F, '- |')'을 열고'(''foo ','bar ') { 수면 2; } exit'이고 부모는 O_ASYNC/F_SETOWN이 아닌'F'에 아무 것도하지 않고 세 개의 SIGIO를 얻습니다. [Example here] (http://pastebin.com/CyjGJtEA), 커널 2.6.18에도 있습니다. – pilcrow

+0

예를 들어 주시겠습니까? 정말 고마워! – Chinaxing