Если вы проверите источник, который вы видите:
> (use 'clojure.repl)
> (source pmap)
(defn pmap
"Like map, except f is applied in parallel. Semi-lazy in that the
parallel computation stays ahead of the consumption, but doesn't
realize the entire result unless required. Only useful for
computationally intensive functions where the time of f dominates
the coordination overhead."
{:added "1.0"}
([f coll]
(let [n (+ 2 (.. Runtime getRuntime availableProcessors))
rets (map #(future (f %)) coll)
step (fn step [[x & xs :as vs] fs]
(lazy-seq
(if-let [s (seq fs)]
(cons (deref x) (step xs (rest s)))
(map deref vs))))]
(step rets (drop n rets))))
([f coll & colls]
(let [step (fn step [cs]
(lazy-seq
(let [ss (map seq cs)]
(when (every? identity ss)
(cons (map first ss) (step (map rest ss)))))))]
(pmap #(apply f %) (step (cons coll colls))))))
(+ 2 (.. Runtime getRuntime availableProcessors))
является большой подсказкой.pmap захватит первые (+ 2 processors)
фрагменты работы и выполнит их асинхронно через future
.Так что, если у вас есть 2 ядра, он будет запускать 4 работы одновременно, пытаясь немного опередить вас, но максимум должен быть 2 + n.
future
в конечном итоге использует агент/ O поток пулов, который поддерживает неограниченное количество потоков.Он будет расти по мере выполнения работы и сокращаться, если нити не используются.