Clojure đã lặp đi lặp lại


12

Trong khi đoạn này

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

in 10 dòng xen kẽ hiển thị các chủ đề khác nhau:

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]]]

như tôi mong đợi, đoạn trích sau:

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

tạo ra 10 chuỗi liên kết gọn gàng với cùng một chủ đề:

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]]                          

trong đó chỉ rõ rằng các hợp đồng tương lai không chạy song song, nhưng mỗi tương lai trong cùng một chuỗi.

Điều này chỉ xảy ra với repeatedly, ngay cả khi tôi nhận ra chuỗi doallđầu tiên, nhưng các vectơ, ranges hoặc các chuỗi khác đều dẫn đến thực hiện song song.

Tại sao tương lai gửi đến cùng một chủ đề khi repeatedlyđược sử dụng?

Cảm ơn!

Câu trả lời:


13

Những công việc này:

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

Vấn đề là rangetạo ra một chuỗi chunked trong khi repeatedlytạo ra một chuỗi unchunked . Bản đồ là lười biếng, vì vậy trong repeatedlytrường hợp bạn đang tạo ra một tương lai, sau đó hủy bỏ nó, sau đó tạo ra tương lai tiếp theo, sau đó hủy bỏ nó. Trong rangetrường hợp chuỗi được phân đoạn để bạn tạo ra tất cả các tương lai và sau đó derefing tất cả chúng.

Đây là một cách thú vị khác để quan sát sự khác biệt giữa hành vi của các chuỗi chunked và ununked.

=> (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

Kích thước của các khối thường là 32 (nhưng tôi nghĩ rằng điều đó không được đảm bảo ở bất cứ đâu), như có thể thấy nếu bạn chạy (first (map prn (range 1000))).

Chunking là một trong những tính năng ẩn của Clojure mà bạn thường tìm hiểu khi lần đầu tiên cắn bạn :)


1
Ái chà! [chèn Âm mưu Keanu Reaves memehere]: Tôi không thấy điều này sẽ đến! Cảm ơn bạn đã trả lời tuyệt vời!
Rick77

1
Không vấn đề gì! Tôi chỉ thấy câu hỏi này vì bạn đã đăng nó trên #clojure trên freenode.
opqdonut
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.