2013-01-25 2 views
0

여러 개의 $ pid를 사용하는 스크립트가 있습니다. 따라서 너무 많은 연결이 발생하면 서버가 멈추고 프로그램이 실행되지 않습니다.살해당한 후 Perl을 자동 실행하는 방법은 무엇입니까?

내 서버에서 자동으로 cron 작업을 다시 시작하고 싶지만 cPanel을 사용하기 때문에 실행할 수 없습니다. 그래서 스크립트에서 자동으로 다시 시작하겠습니다.

나는 그것을 다시 시작하려고 :

kill 9, $pid;  
sleep 60; 

및 출력이 표시됩니다 :

Child Spawned : 15945 

Killed 

를하지만 자동으로 실행 또는 그것은 당신을 찾습니다

답변

3

다시 실행하는 방법을 모른다 포크 당 작업자 풀을 원합니다. 서버 프로세스는 요청을 처리하기 위해 여러 개의 하위 프로세스를 시작하고 자동으로 해당 프로세스를 다시 시작합니다.

기본 템플릿 :

use strict; 
use warnings; 
use POSIX qw(sigprocmask SIG_BLOCK SIG_UNBLOCK SIGINT SIGTERM WNOHANG); 

my $pool_size = 4; # 4 workers 
my %pool; 

# When one or more workers die, delete them from the pool 
$SIG{CHLD} = sub { 
    while ((my $pid = waitpid(-1, WNOHANG)) > 0) { 
     delete $pool{$pid}; 
    } 
}; 

# If a fatal signal is sent to the server, kill all children and exit 
for my $sig (qw(INT TERM)) { 
    $SIG{$sig} = sub { 
     local $SIG{CHLD} = 'IGNORE'; 
     kill $sig => keys %pool; 
     exit; 
    }; 
} 

# HUP = restart all workers 
$SIG{HUP} = sub { 
    print "Caught HUP, restarting workers.\n"; 
    kill TERM => keys %pool 
}; 

# Set up pool 
make_worker() for (1..$pool_size); 

# Maintain population 
while (1) { 
    sleep; # wait for signal 
    while (keys %pool < $pool_size) { 
     make_worker(); 
    } 
} 

exit; 

sub make_worker { 
    # Block INT signal during fork, so parent handler is not called 
    my $sigset = POSIX::SigSet->new(SIGINT, SIGTERM); 
    sigprocmask(SIG_BLOCK, $sigset) or die "Couldn't block signals for fork: $!"; 
    my $pid = fork; 
    die "fork: $!" if !defined $pid; 
    if ($pid) { 
     sigprocmask(SIG_UNBLOCK, $sigset) or die "Couldn't unblock signals for fork: $!"; 
     $pool{$pid} = 1; 
     return; 
    } 
    else { 
     $SIG{$_} = 'DEFAULT' for qw(INT TERM); 
     sigprocmask(SIG_UNBLOCK, $sigset) or die "Couldn't unblock signals for child: $!"; 

     # Your worker code goes here. 

     exit; 
    } 
} 

단순히 루프에서 단일 명령을 다시 시작하기 위해 시도;

while(1) { 
    system("/path/to/your-command", "--args"); 
} 

어떤 이유로 든 명령이 죽 자마자 다시 실행됩니다. 시스템의 종료 코드를 처리하는 것은 그리 간단하지 않기 때문에 IPC :: System :: Simple을 사용하는 것이 좋습니다.

use IPC::System::Simple qw(system); 
use Try::Tiny; 

while(1) { 
    try { system(...) } 
    catch { "Command failed, restarting: $!" }; 
} 

명령이 너무 빨리 종료되었거나 치명적인 오류인지 여부도 감지해야합니다.

관련 문제