क्लोजर "बार-बार" "भविष्य" को क्रमिक रूप से चलाता है


12

जबकि यह स्निपेट है

(dorun 
  (map deref 
    (map #(future 
            (println % (Thread/currentThread))) 
         (range 10))))

अलग-अलग धागों को दिखाती हुई 10 इंटरमिक्स रेखाएँ:

0 #object[java.lang.Thread 0x5f1b4a83 Thread[clojure-agent-send-off-pool-26,5,main]]                                                                                                                           
2 #object[java.lang.Thread 1 0x79dfba1f #object[Thread[clojure-agent-send-off-pool-28,5,main]java.lang.Thread]                                                                                                 
3 4 #object[java.lang.Thread #object[java.lang.Thread 0x7ef7224f Thread[clojure-agent-send-off-pool-27,5,main]0x5f1b4a83 ]Thread[clojure-agent-send-off-pool-26,5,main]]                                       
5                                                                                                                                                                                                              
67  #object[java.lang.Thread #object[0x79dfba1f java.lang.Thread Thread[clojure-agent-send-off-pool-28,5,main]]0x77526645                                                                                      
 8 #object[java.lang.Thread #object[java.lang.ThreadThread[clojure-agent-send-off-pool-29,5,main] ]9 #object[java.lang.Thread 0xc143aa5 0x7ef7224f                                                             Thread[clojure-agent-send-off-pool-31,5,main]]Thread[clojure-agent-send-off-pool-27,5,main]]                                                                                                                       

0x1ce8675f 0x379ae862 Thread[clojure-agent-send-off-pool-30,5,main]Thread[clojure-agent-send-off-pool-32,5,main]]]

जैसा कि मुझे उम्मीद है, निम्नलिखित स्निपेट:

(dorun
  (map deref 
    (map #(future 
            (println % (Thread/currentThread))) 
         (repeatedly 10 #(identity 42)))))

एक ही धागे के साथ बड़े करीने से 10 तार जुड़े हुए हैं:

42 #object[java.lang.Thread 0x1e1b7ffb Thread[clojure-agent-send-off-pool-39,5,main]]                                                                                                                              
42 #object[java.lang.Thread 0x1e1b7ffb Thread[clojure-agent-send-off-pool-39,5,main]]                                                                                                                              
42 #object[java.lang.Thread 0x1e1b7ffb Thread[clojure-agent-send-off-pool-39,5,main]]                                                                                                                              
42 #object[java.lang.Thread 0x1e1b7ffb Thread[clojure-agent-send-off-pool-39,5,main]]                                                                                                                              
42 #object[java.lang.Thread 0x1e1b7ffb Thread[clojure-agent-send-off-pool-39,5,main]]                                                                                                                              
42 #object[java.lang.Thread 0x1e1b7ffb Thread[clojure-agent-send-off-pool-39,5,main]]                                                                                                                              
42 #object[java.lang.Thread 0x1e1b7ffb Thread[clojure-agent-send-off-pool-39,5,main]]                                                                                                                              
42 #object[java.lang.Thread 0x1e1b7ffb Thread[clojure-agent-send-off-pool-39,5,main]]                                                                                                                              
42 #object[java.lang.Thread 0x1e1b7ffb Thread[clojure-agent-send-off-pool-39,5,main]]                                                                                                                              
42 #object[java.lang.Thread 0x1e1b7ffb Thread[clojure-agent-send-off-pool-39,5,main]]                          

जो स्पष्ट रूप से इंगित करता है कि वायदा समानांतर में नहीं चलाया जाता है, लेकिन प्रत्येक एक ही धागे में।

यह केवल तभी होता है repeatedly, भले ही मुझे doallपहले के साथ अनुक्रम का एहसास हो , लेकिन वैक्टर, rangeएस या अन्य अनुक्रम सभी समानांतर निष्पादन में परिणाम देते हैं।

जब repeatedlyउपयोग किया जाता है तो भविष्य को उसी थ्रेड में क्यों भेजा जाता है?

धन्यवाद!

जवाबों:


13

यह काम:

(dorun (map deref (doall (map #(future (println % (Thread/currentThread))) (repeatedly 10 #(identity 42))))))

समस्या यह है कि rangeएक chunked अनुक्रम का repeatedlyउत्पादन करता है जबकि एक unchunked अनुक्रम का उत्पादन करता है । नक्शा आलसी है, इसलिए repeatedlyयदि आप भविष्य का निर्माण कर रहे हैं, तो इसे निष्क्रिय कर दें, फिर अगला भविष्य बनाएं, फिर इसे संक्षिप्त करें। यदि rangeआप सभी वायदा बना रहे हैं तो मामले में अनुक्रम को काट दिया जाता है और फिर derefउन सभी को निगला जाता है।

यहाँ एक और मज़ेदार तरीका है कि ठूंस-ठूंस कर भरे हुए दृश्यों के बीच के अंतर को देखें।

=> (first (map prn (range 10)))
0
1
2
3
4
5
6
7
8
9
nil
=> (first (map prn (repeatedly 10 #(identity 13))))
13
nil

चंक्स का आकार आमतौर पर 32 है (लेकिन मुझे लगता है कि इसकी कहीं भी गारंटी नहीं है), जैसा कि आप चला सकते हैं (first (map prn (range 1000)))

चंकिंग क्लोजर की उन छिपी हुई विशेषताओं में से एक है जो आप आमतौर पर सीखते हैं जब यह पहली बार आपको काटती है :)


1
रुको! [षड़यन्त्र कीनू डालें मेमरेहेयर रीवर्स]: मैंने यह नहीं देखा! शानदार जवाब के लिए धन्यवाद!
रिक

1
कोई दिक्कत नहीं है! मैंने केवल इस प्रश्न को देखा क्योंकि आपने इसे freenode पर #clojure पर पोस्ट किया था।
opqdonut
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.