gpt4 book ai didi

Clojure "repeatedly"使 "future"依次运行

转载 作者:行者123 更新时间:2023-12-03 14:36:51 24 4
gpt4 key购买 nike

虽然这个片段

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

这清楚地表明 future 不是并行运行的,而是每个都在同一个线程中。

这只发生在 repeatedly 上,即使我首先实现了 doall 的序列,但向量、 range 或其他序列都会导致并行执行。

当使用 repeatedly 时,为什么 future 调度到同一个线程?

谢谢!

最佳答案

这有效:

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

问题是 range 产生一个 分块的 序列,而 repeatedly 产生一个 未分块的 序列。 Map 是惰性的,因此在 repeatedly 的情况下,您正在创建一个 future ,然后取消它,然后创建下一个 future ,然后取消它。在 range 的情况下,序列被分块,因此您正在创建所有 future ,然后 deref 所有 future 。

这是观察分块和非分块序列行为之间差异的另一种有趣方式。
=> (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))) 就可以看到。

分块是 Clojure 的隐藏功能之一,你通常在它第一次咬你的时候就学会了 :)

关于Clojure "repeatedly"使 "future"依次运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60561814/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com