我根本没有在Clojure中使用多线程,所以不确定从哪里开始.
我doseq
的身体可以并行运行.我想要的是总是有3个线程运行(留下1个核心空闲),并行地评估主体直到范围耗尽.没有共享状态,没有什么复杂的 - 相当于Python的多处理就可以了.
所以类似于:
(dopar 3 [i (range 100)]
; repeated 100 times in 3 parallel threads...
...)
Run Code Online (Sandbox Code Playgroud)
我应该从哪里开始寻找?有这个命令吗?标准包装?一个很好的参考?
到目前为止,我已经找到了pmap
,并且可以使用它(我如何一次限制为3?看起来它一次使用32个 - 不,源说2 +处理器数量),但似乎这是一个基本原语应该已经存在于某处.
澄清:我真的想控制线程的数量.我有长时间运行的进程并使用相当数量的内存,所以创建一个大数字并希望事情正常运行OK不是一个好方法(例如使用重要的块可用内存).
更新:开始写一个执行此操作的宏,我需要一个信号量(或一个互斥量,或者我可以等待的原子).Clojure中是否存在信号量?或者我应该使用ThreadPoolExecutor?从Java中提取这么多内容似乎很奇怪 - 我认为Clojure中的并行编程应该很容易......也许我正在考虑这完全错误的方式?嗯.代理?
我有一个漫长而懒惰的序列,我想减少并懒惰地测试.一旦两个连续元素彼此不相同=
(或某些其他谓词),我想停止使用生产成本高昂的列表.是的,这听起来像是take-while
,但请进一步阅读.
我想写一些简单而优雅的东西(假装一分钟every?
就像这样reduce
):
(every? = (range 100000000))
Run Code Online (Sandbox Code Playgroud)
但这不是懒惰的工作,所以它挂在无限的seqs.我发现这几乎和我想要的一样:
(apply = (range 100000000))
Run Code Online (Sandbox Code Playgroud)
但是,我注意到序列分块导致创建和测试额外的,不必要的元素.至少,这就是我认为这是在下面的代码中发生的事情:
;; Displays chunking behavior in groups of four on my system and prints 1 2 3 4
(apply = (map #(do (println %) %) (iterate inc 1)))
;; This prints 0 to 31
(apply = (map #(do (println %) %) (range)))
Run Code Online (Sandbox Code Playgroud)
我找到了一种解决方法take-while
,并count
检查所采用的元素数量,但这很麻烦.
我应该礼貌地向Rich Hickey建议他正确地进行了一些组合reduce
和every?
短路,还是我错过了一些已经存在的明显方法?
编辑:两种人发布了避免在懒惰序列上进行分块的解决方案,但是如何避免在进行分块时使用分块apply
,这似乎在四个分组中消耗?
编辑#2:正如Stuart Sierra所说,我独立发现,这实际上并不是分块.它只是正常应用,所以我会把它叫做关闭并给他答案.对于那些感兴趣的人,我在一个单独的答案中包含了一个小函数来完成问题的减少部分.