2010-12-31 2 views
1

포크 때 호출되지이 내 코드 않았다 불평 :POE는 POE :: 커널의 실행 방법은 내가

if ($DAEMON) { 
       my $pid = fork(); 
       if (not defined $pid) { 
             print "Unable to start daemon.\n"; 
             exit(1); 
             } 
       elsif ($pid == 0) { 
            open STDOUT, '>', '/dev/null'; 
            open STDERR, '>', '/dev/null'; 
            _create_sessions($self, $settings); 
            $poe_kernel->run; 
            } 
       else { print "Script forked to background with PID $pid\n"; } 
       } 
else { 
     _create_sessions($self, $settings); 
     $poe_kernel->run; 
     } 

$ DAEMON = 1, 그것은 POE :: 커널의 run() 메소드가 호출되지 것을 불평 ,하지만 위의 코드에서 볼 수 있듯이, 나는 이미 그것을했다. 스크립트는 데몬 모드에서 완벽하게 작동하지만 나는 그 경고를 없애거나 그것이 왜 그렇게 말하고 있는지 이해할 수 없습니다. 나 또한 $ poe_kernel-> has_forked()를 호출 해 보았는데 그 차이도 없었다.

나는 생각이 없습니다. 어떤 제안?

에 추가 : 어쩌면 충분히 명확하지 않을 수 있습니다. 아래의 코드는 세션을 생성하고 커널을 실행합니다.

_create_sessions($self, $settings); 
$poe_kernel->run; 

완벽하게 정상적으로 작동합니다. 포크 자식 내에서 동일한 코드가 실행될 때만 스크립트를 백그라운드로 보낼 수 있습니다. POE :: Kernel의 run 메소드가 호출되지 않았다고합니다. 스크립트는 백그라운드로 들어가서 커널이 실제로 실행 중임을 의미하는 것처럼 작동합니다. 그 성가신 경고를 없애기 위해서만보고 있습니다.

답변

2

ysth가 맞습니다. POE :: Session 인스턴스는 부모 프로세스에서 생성되었지만 실행할 수있는 기회가 주어지지 않았기 때문에 경고가 발생합니다.

% perl -wle 'use POE; POE::Session->create(inline_states=>{_start => sub {}})' 
40023: Sessions were started, but POE::Kernel's run() method was never 
40023: called to execute them. This usually happens because an error 
40023: occurred before POE::Kernel->run() could be called. Please fix 
40023: any errors above this notice, and be sure that POE::Kernel->run() 
40023: is called. See documentation for POE::Kernel's run() method for 
40023: another way to disable this warning. 

위의 예에서 40023은 문제점이 발견 된 프로세스 ID입니다.

그것은 활성 스레드와 종료에 대한 펄의 경고 비슷 : 당신의 코드는 세션을 생성하고 자식 프로세스에서 실행됩니다 보여줍니다

% perl -wle 'use threads; threads->create(sub { sleep 3600 }); ' 
Perl exited with active threads: 
    1 running and unjoined 
    0 finished and unjoined 
    0 running and detached 

동안, 나는 세션이 이전 또는 이후에 생성됩니다 생각한다. 상위 프로세스가 스 니펫에서 종료되지 않으므로 나중에 실행이 어디로 진행되는지 알 수 없습니다.

또한 하위 프로세스에서 POE :: Kernel-> has_forked()를 호출해야합니다. 코드 스 니펫에서 이러한 일이 발생하는지 여부를 알 수 없습니다.

Daemonizing 할 때 모든 세션 인스턴스화를 하위 프로세스로 이동하는 것이 올바른 해결책입니다. 가능한 한가지 해결 방법은 POE :: Kernel을 사용하고 POE :: Kernel-> run()을 호출하고 세션이 실제로 생성되기 전에 호출하는 것입니다. run()은 세션이 없으므로 즉시 반환되지만 호출은 경고 대상 조건을 충족시킵니다. 그것은 "네, 그렇습니다.하지만 저는 제가하고있는 것을 압니다."라고 말하는 방식입니다.

+0

이 문제가 해결되었습니다. 나는 POE :: Component :: Resolver가 임포트시에 스스로를 설정한다고 생각한다. 포크라면 POE가 불평 할 것이고 자식 프로세스가 제대로 작동하지 않을 것이다. 자식 프로세스에서 $ poe_kernel->을 실행하면 리졸버가 종료되고 포크가 올바르게 작동합니다. – rjh

1

문서에서 POE :: Kernel의 실행은 일반적으로 클래스 메소드로 호출됩니다. $ poe_kernel은 무엇입니까?

어딘가에 세션을 시작한 것 같지만 POE :: Kernel-> run();

업데이트 : 표시되는 메시지가 경고와 함께 출력되고 자녀에게 STDERR을 (를) 던지고 있기 때문에 경고하는 부모라고 생각합니다. 무언가 (POE를로드하고 $ poe_kernel을 설정하는 코드에서 코드에서 실제로 의도하지 않게 세션이 생성되고 있음).

코드를 짧지 만 실행 가능한 예제로 줄이고 직접 문제를 찾거나 다른 사용자가 문제를 쉽게 찾을 수 있도록하십시오.

+1

$ poe_kernel은 POE :: Kernel과 동일합니다. run()은 모든 세션이 시작된 후에 한 번만 호출되어야합니다. 경고는 fork() 자식 내부에서만 발생합니다. – perlit