2010-12-30 7 views
13

क्लोजर में मैं लगातार चल रही पृष्ठभूमि प्रक्रिया कैसे बना सकता हूं? एक लूप के साथ "भविष्य" का उपयोग कर रहा है जो सही तरीके से कभी समाप्त नहीं होता है?क्लोजर में मैं लगातार चल रही पृष्ठभूमि प्रक्रिया कैसे बना सकता हूं?

उत्तर

14

आप केवल एक फ़ंक्शन के साथ एक थ्रेड शुरू कर सकते हैं जो हमेशा के लिए चलता है।

(defn forever [] 
    ;; do stuff in a loop forever 
) 

(.start (Thread. forever)) 

आप इस प्रक्रिया से बाहर निकलने के ब्लॉक करने के लिए पृष्ठभूमि धागा नहीं करना चाहते हैं, यह एक डेमॉन धागा बनाने के लिए सुनिश्चित करें: आप कुछ और चालाकी आप java.util उपयोग कर सकते हैं चाहते हैं

(doto 
    (Thread. forever) 
    (.setDaemon true) 
    (.start)) 

एक निष्पादक सेवा बनाने के लिए .concurrent.Executors कारखाना। इससे धागे के पूल बनाने, कस्टम थ्रेड कारखानों, कस्टम आने वाली कतारों आदि का उपयोग करना आसान हो जाता है।

claypoole lib कुछ कार्य निष्पादन सामग्री को अधिक क्लोजर-अनुकूल एपीआई में लपेटता है यदि आप यही चाहते हैं की ओर।

5

मेरे सरल उच्च क्रम अनंत लूप समारोह (वायदा का उपयोग कर):

(def counter (atom 1)) 

(defn infinite-loop [function] 
    (function) 
    (future (infinite-loop function)) 
    nil) 

;; note the nil above is necessary to avoid overflowing the stack with futures... 

(infinite-loop 
    #(do 
    (Thread/sleep 1000) 
    (swap! counter inc))) 

;; wait half a minute.... 

@counter 
=> 31 

मैं दृढ़ता से परिणाम (उदाहरण में ऊपर स्टोर करने के लिए काउंटर के अनुसार एक परमाणु या Clojures से एक का उपयोग अन्य संदर्भ प्रकार की सिफारिश)।

कुछ ट्वीविंग के साथ आप थ्रेड-सुरक्षित तरीके से प्रक्रिया को शुरू/बंद/रोकने के लिए इस दृष्टिकोण का उपयोग भी कर सकते हैं (उदाहरण के लिए फ्लैग का परीक्षण करें कि लूप के प्रत्येक पुनरावृत्ति में (फ़ंक्शन) निष्पादित किया जाना चाहिए) ।

+2

पी। यह जानना भी अच्छा है कि इस दृष्टिकोण का ओवरहेड बहुत कम है - यदि आप थ्रेड/नींद – mikera

+0

हटाते हैं तो आप एक मिलियन काउंटर वृद्धि को एक सेकंड से अधिक प्राप्त कर सकते हैं। एक और सरल कार्यान्वयन जो स्टैक का उपभोग नहीं करेगा '(अनंत [एफ सेकेंड] (भविष्य (लूप [] (एफ) (थ्रेड/नींद (* सेकंड 1000)) (पुनरावृत्ति)))) –

+0

@ जेम्स - मेरा कार्यान्वयन या तो ढेर का उपभोग नहीं करता है। तथ्य यह है कि 'अनंत-लूप' के लिए रिकर्सिव कॉल भविष्य के अंदर है जिसका अर्थ है कि यह मूल फ़ंक्शन के स्टैक फ्रेम में आवर्ती नहीं है। – mikera

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