2010-10-19 17 views
24

Bazen sistem çağrımı hiç bitmeyen bir duruma geçer. Bunun için, belirli bir süre sonra çağrıdan çıkabilmek istiyorum.Perl sistem çağrısı için zaman aşımı sınırını nasıl belirleyebilirim?

system için zamanaşımı sınırı belirtmenin bir yolu var mı?

system("command", "arg1", "arg2", "arg3"); 

Ben aşımı ulimit gibi bazı OS özel işlevleri kullanarak Taşınabilirlik için Perl kodu içinde uygulunmamakta ve olmak istiyorum.

+1

Bu Sayabileceğimden daha yinelenen daha katıdır: http://stackoverflow.com/questions/2679582/how-can-i-kill-a-perl-system-call-after-a -timeout http://stackoverflow.com/questions/1962985/how-can-i-timeout-a-forked-process-that-might-hang http://stackoverflow.com/questions/2423288/ways-to-do -timeouts-in-perl http://stackoverflow.com/questions/3427401/perl-make-script-timeout-after-x-number-of-seconds http://stackoverflow.com/questions/1165316/how-can -i-limit-in-a-perl-bet-of-a-perl-komut dosyası sadece birkaçıdır. – Ether

cevap

27

alarm işlevine bakın. pod Örnek: Time::Out

use Time::Out qw(timeout) ; 

timeout $nb_secs => sub { 
    # your code goes were and will be interrupted if it runs 
    # for more than $nb_secs seconds. 
}; 

if ([email protected]){ 
    # operation timed-out 
} 
+0

Bu işe yarıyor gibi görünüyor, ancak sorun, ana Perl işlemi zaten ölmüş olsa bile, sistem çağrısı yoluyla yürütülen komutun çalışmaya devam etmesidir. Perl komut dosyasının bitmeden önce onu öldürebilmemiz için sistem çağrısı tarafından çalıştırılan işlemin işlem tanıtıcısı/tanıtıcısı nasıl elde edileceğini bilen var mı? – antred

+1

@antred - İşlem kimliğini almak için, ['system'] (http: // perldoc) yerine [' fork'] (http://perldoc.perl.org/perlfork.html) kullanarak yeniden yazmanız gerekir. perl.org/functions/system.html). Bunu daha kolay hale getirmek için IPC :: Cmd & IPC :: Run gibi modüllere bir göz atın (bu bağlamda). – draegtun

13

Sen IPC::Run 'ın çalışma yöntemi yerine sistemini kullanabilirsiniz:

eval { 
    local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required 
    alarm $timeout; 
    $nread = sysread SOCKET, $buffer, $size; 
    alarm 0; 
}; 
if ([email protected]) { 
    die unless [email protected] eq "alarm\n"; # propagate unexpected errors 
    # timed out 
} 
else { 
    # didn't 
} 

sarma bu kadar biraz daha güzel, eg CPAN modülü vardır. ve bir zaman aşımı ayarlayın.

3

System::Timeout nasıl?

Bu modül belirtilen saniye sonra zaman aşımına izin vermek için system'u genişletir.

timeout("3", "sleep 9"); # timeout exit after 3 seconds 
+0

Yalnızca içerik yanıtları içerik değiştiğinde veya değiştiğinde yanıtlar işe yaramaz. Sorunun eşleşmesi için, bağlantının ilgili bölümlerini yanıtlanmış şekilde uyarlayın. – miken32

+0

Potansiyel bir çözümün bağlantısı her zaman bekler, ancak lütfen [linkin etrafına bağlam ekleyin] (http://meta.stackexchange.com/a/8259), böylece diğer kullanıcılarınız ne olduğu ve neden orada olduğu hakkında fikir sahibi olurlar. . Hedef siteye ulaşılamaması veya sürekli olarak çevrimdışı olması durumunda, her zaman önemli bir bağlantının en alakalı bölümünü belirtin. Harici bir siteye bağlantıdan çok daha fazla olmanın, [Neden ve bazı cevaplar nasıl siliniyor?] (Http://stackoverflow.com/help/deleted-answers) için olası bir neden olduğunu göz önünde bulundurun. – FelixSFD

+1

@ miken32 Düzenlendi. – melpomene