2009-07-24 13 views
8

मैं अपने काम के लिए रूबी में एक नौकरी-शेड्यूलिंग एप्लिकेशन लिख रहा हूँ (मुख्य रूप से एक तय आवृत्ति पर विभिन्न प्रोटोकॉल का उपयोग फ़ाइलों को स्थानांतरित करने)नींद() एक नौकरी-शेड्यूलिंग एप्लिकेशन

के मुख्य पाश के लिए एक अच्छा विचार है

मेरा मुख्य पाश इस तरह दिखता है:

while true do 
    # some code to launch the proper job 
    sleep CONFIG["interval"] 
end 

यह एक आकर्षण की तरह काम कर रहा है, लेकिन मैं वास्तव में अगर यह आवेदन CPU- सघन सॉफ्टवेयर चल रहा है के साथ एक सर्वर पर चला सकता है के रूप में काफी सुरक्षित है यकीन नहीं है।

क्या एक ही चीज करने का कोई और तरीका है, या sleep() मेरे मामले में पर्याप्त सुरक्षित है?

उत्तर

5

नींद का उपयोग करना संभवतः त्वरित और गंदे चीजों के लिए ठीक है। लेकिन उन चीज़ों के लिए जिनकी थोड़ी अधिक मजबूती या विश्वसनीयता की आवश्यकता है, मैं सुझाव देता हूं कि नींद बुराई है :) सोने के साथ समस्या यह है कि धागा है (मैं यहां विंडोज़ मान रहा हूं ...) वास्तव में सो रहा है - शेड्यूलर थ्रेड नहीं चलाएगा नींद अंतराल पारित होने के कुछ समय बाद तक।

इस समय के दौरान, थ्रेड कुछ भी नहीं जाग जाएगा। इसका मतलब है कि इसे रद्द नहीं किया जा सकता है, या किसी प्रकार की घटना को संसाधित करने के लिए जागृत नहीं किया जा सकता है। बेशक, प्रक्रिया को मार दिया जा सकता है, लेकिन यह सोने के धागे को जागने और साफ करने का अवसर नहीं देता है।

मैं रूबी से परिचित नहीं हूं, लेकिन मुझे लगता है कि इसमें कई चीजों की प्रतीक्षा करने के लिए किसी प्रकार की सुविधा है। यदि आप कर सकते हैं, तो मेरा सुझाव है कि नींद का उपयोग करने के बजाय, आप दो चीजें \

  1. एक टाइमर जो समय-समय पर काम को करने के लिए थ्रेड बनाता है।
  2. एक ऐसी घटना जो सेट की जाती है जब उसे प्रक्रिया को रद्द करने या काफी (उदाहरण के लिए नियंत्रण-सी फंसाना) की आवश्यकता होती है।

यह कुछ बेहतर होगा यदि काम करने की आवश्यकता को इंगित करने के लिए किसी प्रकार की घटना का उपयोग किया जा सके। यह टाइमर पर मतदान से बच जाएगा।यह आम तौर पर कम संसाधन उपयोग और एक अधिक प्रतिक्रियाशील प्रणाली की ओर जाता है।

3

यदि आपको सटीक अंतराल की आवश्यकता नहीं है, तो यह मुझे समझ में आता है। यदि आपको बिना किसी बहाव के नियमित समय पर जागने की आवश्यकता है, तो आप शायद किसी प्रकार के बाहरी टाइमर का उपयोग करना चाहते हैं। लेकिन जब आप सोते हैं, तो आप CPU संसाधनों का उपयोग नहीं कर रहे हैं। यह टास्क स्विच महंगा है।

7

किसी भी समय मुझे ब्लॉक करने की आवश्यकता महसूस होती है, मैं एक ईवेंट लूप का उपयोग करता हूं; आमतौर पर libev। यहाँ एक रूबी बाध्यकारी है:

http://rev.rubyforge.org/rdoc/

असल में, sleep बिल्कुल ठीक अगर आप अपने प्रक्रिया कुछ और होने की पृष्ठभूमि में चल रहा बिना सो जाओ करना चाहते हैं। यदि आप कभी भी अन्य चीजें करना चाहते हैं, हालांकि, नींद की तरह और टीसीपी कनेक्शन या फ़ाइलहेडल को पठनीय बनने की भी प्रतीक्षा करें, तो आपको इवेंट लूप का उपयोग करना होगा। तो, शुरुआत में केवल एक का उपयोग क्यों न करें?

आपके आवेदन के प्रवाह होगा:

main { 
    Timer->new(after => 0, every => 60 seconds, run => { <do your work> }) 
    loop(); 
} 

आप अन्य सामान करना चाहते हैं, तो आप सिर्फ द्रष्टा बनाते हैं, और यह आप के लिए होता है। (जो नौकरियां आप चल रहे हैं वे भी वॉचर्स बना सकते हैं।)

+0

यदि स्थिति पूरी हो जाती है तो आप इस लूप को कैसे तोड़ते हैं? – Fadi

2

यह सोते समय सीपीयू का उपयोग नहीं करेगा, लेकिन यदि आप लंबे समय तक सो रहे हैं तो मैं दौड़ने वाले रूबी दुभाषिया के बारे में अधिक चिंतित हूं, जबकि यह था कुछ भी नहीं कर रहा हूँ। यह एक सौदा का बड़ा नहीं है।

+0

यदि मैं सही ढंग से समझता हूं, तो इसका मतलब है कि यह स्मृति संसाधनों का उपयोग करता है लेकिन सोते समय CPU संसाधन नहीं? –

3

जबकि sleep(timeout) कुछ डिज़ाइनों के लिए बिल्कुल उपयुक्त है, ध्यान में रखना एक महत्वपूर्ण चेतावनी है।

रूबी SA_RESTART साथ संकेत संचालकों को स्थापित करता है (here देखें), जिसका अर्थ है कि आपके sleep (या समतुल्य select(nil, nil, nil, timeout)) आसानी से बाधित नहीं किया जा सकता है। आपका सिग्नल हैंडलर आग लगाएगा, लेकिन कार्यक्रम sleep पर वापस जायेगा। यदि आप SIGTERM पर समय पर प्रतिक्रिया करना चाहते हैं तो यह असुविधाजनक हो सकता है।

पर विचार करें कि ...

#! /usr/bin/ruby 
Signal.trap("USR1") { puts "Hey, wake up!" } 
Process.fork() { sleep 2 and Process.kill("USR1", Process.ppid) } 
sleep 30 
puts "Zzz. I enjoyed my nap." 

... के बारे में 30 सेकंड निष्पादित करने के लिए ले जाएगा, बल्कि 2.

समाधान के लिए की तुलना में, आप के बजाय अपने सिग्नल हैंडलर में एक अपवाद फेंक सकता है, जो उपरोक्त नींद (या कुछ और!) को बाधित करेगा। आप select-आधारित लूप पर भी स्विच कर सकते हैं और सिग्नल प्राप्त होने पर "प्रारंभिक" जागने के लिए self-pipe trick का एक संस्करण उपयोग कर सकते हैं। जैसा कि अन्य ने बताया है, पूरी तरह से फीचर्ड इवेंट लाइब्रेरी भी उपलब्ध हैं।

+1

यह बहुत सुंदर नहीं है, लेकिन क्या यह सिर्फ '10. टाइम्स {नींद 1}' करने के लिए काम करेगा? यह 10 के लिए सोने की तरह होगा लेकिन आपको 1 सेकंड का जवाब देने के लिए अधिकतम समय देगा। –

+0

@ ब्रायन: हाँ यह काम करेगा। हाँ यह बहुत सुंदर है। – pilcrow

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