2015-05-20 7 views
5

में धागा बनाम http://martintrojer.github.io/clojure/2013/07/07/coreasync-and-blocking-io/ से:जाने ब्लॉक core.async

में थोड़ा और अधिक ठोस है जब हम core.async का उपयोग कर कुछ HTTP GET अनुरोध जारी करने के लिए कोशिश देखते हैं क्या होता है प्राप्त करने के लिए। आइए क्लोज-एचटीएमएल के माध्यम से ब्लॉकिंग आईओ का उपयोग करके बेवकूफ समाधान से शुरू करें।

(defn blocking-get [url] 
    (clj-http.client/get url)) 


(time 
    (def data 
    (let [c (chan) 
      res (atom [])] 
     ;; fetch em all 
     (doseq [i (range 10 100)] 
     (go (>! c (blocking-get (format "http://fssnip.net/%d" i))))) 
     ;; gather results 
     (doseq [_ (range 10 100)] 
     (swap! res conj (<!! c))) 
     @res 
     ))) 

यहाँ हम 90 कोड के टुकड़े को लाने (समानांतर में) ब्लॉक जाना का उपयोग कर कोशिश कर रहे हैं (और आईओ अवरुद्ध)। इसमें काफी समय लगा, और ऐसा इसलिए है क्योंकि गो ब्लॉक थ्रेड लंबे समय तक चल रहे आईओ ऑपरेशंस द्वारा "छेड़छाड़" किए जाते हैं। गो ब्लॉक को सामान्य धागे पर स्विच करके स्थिति में सुधार किया जा सकता है।

(time 
    (def data-thread 
    (let [c (chan) 
      res (atom [])] 
     ;; fetch em all 
     (doseq [i (range 10 100)] 
     (thread (>!! c (blocking-get (format "http://fssnip.net/%d" i))))) 
     ;; gather results 
     (doseq [_ (range 10 100)] 
     (swap! res conj (<!! c))) 
     @res 
     ))) 

इसका क्या मतलब है "जाना ब्लॉक धागे लंबे चल आईओ आपरेशन द्वारा hogged कर रहे हैं" है?

उत्तर

4

गो ब्लॉक का उद्देश्य हल्के वजन सहकारी धागे का एक प्रकार होना है; वे पूल में कुछ धागे का उपयोग करके पूर्ण जेवीएम धागे की तुलना में कम ओवरहेड के साथ थ्रेड-जैसे व्यवहार प्रदान करते हैं और पार्क - उदाहरण के लिए, <! का उपयोग करते हुए चैनल पर प्रतीक्षा करते समय ब्लॉक को स्विच करना। जब आप JVM थ्रेड को अवरुद्ध करते हैं तो ब्लॉक में कोई विधि कॉल करते समय थ्रेड-स्विचिंग काम नहीं कर सकती है, इसलिए आप जल्दी से JVM थ्रेड से बाहर हो जाते हैं। अधिकांश मानक जावा (और क्लोजर) आईओ ऑपरेशंस प्रतीक्षा करते समय वर्तमान धागे को अवरुद्ध कर देंगे।

+0

हालांकि मैं क्लोजर फोर्कजोइन का भी उपयोग करता हूं लेकिन ऐसा लगता है कि ऐसा नहीं है। यह एक साधारण फिक्स्ड थ्रेडपूल का उपयोग करता है। क्या इसका कोई कारण है? स्कैला फोर्कज सिक्के और निष्पादक को यह भी बता सकते हैं कि यह कोड अवरुद्ध कर रहा है ताकि अधिक धागे को बढ़ाने की सलाह दी जा सके। (http://docs.scala-lang.org/overviews/core/futures.html) और (http://dev.clojure.org/display/design/Async+Executor) – ClojureMostly

2

इसका क्या अर्थ है कि "ब्लॉक थ्रेड को लंबे समय तक चल रहे आईओ ऑपरेशंस द्वारा दबाया जाता है"?

गो ब्लॉक * की सेवा करने के लिए समर्पित सीमित थ्रेड हैं। यदि आप उन थ्रेडों में से किसी एक पर अवरुद्ध I/O ऑपरेशन करते हैं, तो इसका उपयोग तब तक नहीं किया जा सकता जब तक कि ऑपरेशन पूरा न हो जाए (जब तक थ्रेड बाधित नहीं हो जाता)। गैर-ब्लॉक ब्लॉक धागे (यानी, thread फ़ंक्शन से लौटाए गए धागे) के लिए यह भी सच है, लेकिन गैर-ब्लॉक ब्लॉक थ्रेड सीमित गो ब्लॉक थ्रेड पूल से नहीं आते हैं। तो यदि आप एक ब्लॉक ब्लॉक में I/O अवरुद्ध करते हैं, तो आप "होगिंग" कर रहे हैं जो ब्लॉक के थ्रेड को अन्य गोले ब्लॉक द्वारा उपयोग करने से रोकते हैं, भले ही थ्रेड कोई वास्तविक काम नहीं कर रहा हो (यह सिर्फ I/O की प्रतीक्षा कर रहा है ऑपरेशन)।

* यह संख्या वर्तमान में 42 + JVM के लिए उपलब्ध प्रोसेसर की संख्या होती है।

+0

यह नेक्रो को क्षमा करें, लेकिन ' यह 2 + उपलब्ध प्रोसेसर नहीं है? 42 + नहीं ...? – Carcigenicate

+0

क्या गो-ब्लॉक थ्रेड पूल प्रति-प्रक्रिया या प्रति-जेवीएम या प्रति-मशीन है? – tar

+0

प्रति-प्रक्रिया और प्रति-जेवीएम के बीच क्या अंतर है? – erikprice

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