为什么Clojure在完成计算后会挂起?

时间:2010-04-12 14:22:56

标签: clojure parallel-processing

我正在尝试并行过滤元素。对于每个元素,我需要执行距离计算以查看它是否足够接近目标点。不要因为这样做已经存在数据结构,我现在只做初步实验。

无论如何,我想运行一些非常基本的实验,我生成随机向量并过滤它们。这是我执行所有这些

的实现
(defn pfilter [pred coll]
  (map second
    (filter first
      (pmap (fn [item] [(pred item) item]) coll))))

(defn random-n-vector [n]
  (take n (repeatedly rand)))

(defn distance [u v]
  (Math/sqrt (reduce + (map #(Math/pow (- %1 %2) 2) u v))))

(defn -main [& args]
  (let [[n-str vectors-str threshold-str] args
        n (Integer/parseInt n-str)
        vectors (Integer/parseInt vectors-str)
        threshold (Double/parseDouble threshold-str)
        random-vector (partial random-n-vector n)
        u (random-vector)]
    (time (println n vectors 
      (count 
        (pfilter 
          (fn [v] (< (distance u v) threshold))
          (take vectors (repeatedly random-vector))))))))

代码执行并返回我期望的内容,即参数n(向量的长度),向量(向量的数量)以及比目标向量的阈值更接近的向量的数量。我不明白为什么程序会在终止之前再挂一分钟。

以下是演示错误

的运行输出
$ time lein run 10 100000 1.0
     [null] 10 100000 12283
     [null] "Elapsed time: 3300.856 msecs"

real    1m6.336s
user    0m7.204s
sys 0m1.495s

关于如何一般过滤的任何评论也非常受欢迎,因为我还没有确认pfilter确实有效。

1 个答案:

答案 0 :(得分:22)

您需要调用shutdown-agents来杀死支持pmap使用的线程池的线程。

关于pfilter,它应该有效,但运行速度比filter慢,因为您的谓词很简单。并行化不是免费的,因此您必须为每个线程提供中等密集型任务以抵消多线程开销。在过滤之前批量处理您的项目。