2010-03-11 13 views
15

मैं अक्सर पर्ल में एक विशेष कोड टुकड़ा का चलने का समय के लिए एक ऊपरी बाध्य स्थापित करने के लिए निम्नलिखित पैटर्न का उपयोग करें:पर्ल में टाइमआउट करने के तरीके?

my $TIMEOUT_IN_SECONDS = 5; 
eval { 
    local $SIG{ALRM} = sub { die "alarm\n" }; 
    alarm($TIMEOUT_IN_SECONDS); 
    # do stuff that might timeout. 
    alarm(0); 
}; 
if ([email protected]) { 
    # handle timeout condition. 
} 

मेरे सवालों का:

  • इस यह करने के लिए सही तरीका है?
  • क्या ऐसी कोई परिस्थितियां हैं जिसके अंतर्गत चलने का समय $ TIMEOUT_IN_SECONDS से अधिक हो सकता है, या उपरोक्त विधि बुलेट प्रूफ है?
+1

आपका eval एक बुरा बग के लिए कमजोर है। एक विस्तृत स्पष्टीकरण के लिए Try :: छोटे दस्तावेज़ पढ़ें: http://search.cpan.org/perldoc?Try::Tiny – daotoad

उत्तर

9

शायद आप Sys::SigAction पर देखना चाहते हैं। मैंने इसे स्वयं नहीं इस्तेमाल किया है, लेकिन इसमें some glowing reviews है।

यह देखने के लिए एक बात यह है कि "सामान जो समय-समय पर हो सकता है" sleep या alarm स्वयं का उपयोग करता है। साथ ही, एरर हैंडलिंग कोड में, मुझे लगता है कि आप टाइमआउट के अलावा त्रुटियों के लिए तैयार हैं।

+0

क्या आप इस मामले की व्याख्या कर सकते हैं जब एप्लिकेशन नींद का उपयोग कर रहा हो? और, इसे कैसे हल करें? –

2

सिग्नल हैंडलिंग के साथ ख्याल रखना। पर्ल को सिंक्रोन को अतुल्यकालिक रूप से प्राप्त होता है और अगर किसी सिग्नल को प्राप्त किया जाता है तो कॉलबैक द्वारा दूसरे सिग्नल को संभाला जा रहा है, तो वे एक दूसरे के साथ खो सकते हैं या हस्तक्षेप कर सकते हैं।

घटना से निपटने पुस्तकालयों 'Win32 समर्थन पर्ल में सुंदर तो इतना है (मैं गैर cygwin Win32 समर्थन करने के लिए किया है), तो मैं आम तौर पर समय समाप्ति के लिए एक सरल मतदान पाश का उपयोग करें:

use Time::HiRes qw(sleep); 

sub timeout { 
    my $timeout = shift; 
    my $poll_interval = shift; 
    my $test_condition = shift; 
    until ($test_condition->() || $timeout <= 0) { 
    $timeout -= $poll_interval; 
    sleep $poll_interval; 
    } 
    return $timeout > 0; # condition was met before timeout 
} 

my $success = timeout(30, 0.1, \&some_condition_is_met); 

निष्क्रिय टाइमर आसानी से उपयोगकर्ता- या कॉलर-कॉन्फ़िगर करने योग्य बनाया जा सकता है और जब तक कि आप एक बेहद तंग लूप नहीं कर रहे हों या लूप पर प्रतीक्षा करने वाले एकाधिक कॉलर हों (जहां आप रेस या डेड लॉक के साथ समाप्त हो सकते हैं), यह एक सरल, भरोसेमंद और क्रॉस है एक टाइमआउट लागू करने के लिए प्लेटफार्म तरीका।

यह भी ध्यान रखें कि लूप ओवरहेड का अर्थ यह होगा कि आप गारंटी नहीं दे सकते कि टाइमआउट पूरी तरह से मनाया जाता है। $ test_condition, कमी, कचरा संग्रह, आदि हस्तक्षेप कर सकते हैं।

+1

यह सवाल का जवाब नहीं देता है। यह कोड ओपी के कोड के समान उद्देश्य प्राप्त नहीं करेगा। अगर some_condition_is_met() कभी वापस नहीं आता है, तो प्रोग्राम लटका होगा। –

4

आप Time::Out भी आजमा सकते हैं। मुझे वाक्यविन्यास और नेस्टेड टाइमआउट समर्थित हैं ..

+1

+1 यह मॉड्यूल आपके लिए नेस्टेड टाइमआउट आदि के बारे में सभी चिंताओं को संभालता है ताकि आपको सभी किनारे के मामलों के बारे में चिंता न करें। यह अलार्म है कि कोशिश करें :: छोटे को eval करना है। – mikew

+0

समय :: आउट मॉड्यूल थ्रेडसेफ है? मेरे मामले में मुझे अपने आवेदन में प्रति थ्रेड चलाने वाले टाइमआउट की आवश्यकता है। – reedog117

+0

@ reedog117: मुझे नहीं पता ... –

संबंधित मुद्दे