multithreading - 在 Clojure 中使用 pmap 来并行化归并排序。程序在结束前挂起约 1 分钟,然后终止

标签 multithreading concurrency clojure terminate pmap

我正在 Clojure 中编写一个程序,该程序从文本文件 10000.txt (这有 10k 个无符号整数)中获取输入。然后我将该列表传递给我的合并排序函数(一个单线程,2、4、8、16、32线程)。

当我运行程序时,通过键入“clojure test.clj”,它会输出每个函数的耗时,但程序不会终止。

它卡在那里,就像它在等待输入或即将输出其他东西一样。
然后大约 1 分钟后,程序最终终止。幕后一定有什么事情发生。关于它是什么/输入后我需要做什么来终止程序的任何想法?

程序的输出(终止前)这是它挂起大约 1 分钟的地方

Terminal Output Picture

(use 'clojure.java.io)
(require '[clojure.string :as str])

;Read file and store into numbers, as a string
(def numbers (slurp "10000.txt"))

;Parse the string 'numbers', ignore the spaces 
;and save the result into x1 (a lazy-seq of integers)
(def x1 (map #(Integer/parseInt %) (str/split numbers #"\s+")))

;Function that performs the operation of merge sort algorithm
(defn merge-lists [left right]
  (loop [head [] L left R right]
    (if (empty? L) (concat head R)
        (if (empty? R) (concat head L)
            (if (> (first L) (first R))
              (recur (conj head (first R)) L (rest R))
              (recur (conj head (first L)) (rest L) R))))))

;The other merge-sort functions use pmap to run merge sort in parallel
;Using 1,2,4,8,16,32 threads
(defn naive-merge-sort [list]
  (if (< (count list) 2) list
      (apply merge-lists
             (map naive-merge-sort
                  (split-at (/ (count list) 2) list)))))

(defn parallel-merge-sort-2 [list]
  (if (< (count list) 2) list
      (apply merge-lists
             (pmap naive-merge-sort
                   (split-at (/ (count list) 2) list)))))

(defn parallel-merge-sort-4 [list]
  (if (< (count list) 2) list
      (apply merge-lists
             (pmap parallel-merge-sort-2
                   (split-at (/ (count list) 2) list)))))

(defn parallel-merge-sort-8 [list]
  (if (< (count list) 2) list
      (apply merge-lists
             (pmap parallel-merge-sort-4
                   (split-at (/ (count list) 2) list)))))

(defn parallel-merge-sort-16 [list]
  (if (< (count list) 2) list
      (apply merge-lists
             (pmap parallel-merge-sort-8
                   (split-at (/ (count list) 2) list)))))

(defn parallel-merge-sort-32 [list]
  (if (< (count list) 2) list
      (apply merge-lists
             (pmap parallel-merge-sort-16
                   (split-at (/ (count list) 2) list)))))

;Run each of the merge-sort functions and output their time
(time (naive-merge-sort x1))
(time (parallel-merge-sort-2 x1))
(time (parallel-merge-sort-4 x1))
(time (parallel-merge-sort-8 x1))
(time (parallel-merge-sort-16 x1))
(time (parallel-merge-sort-32 x1))

这是我的 10000.txt 文件:https://pastebin.com/5vKXUk1u

我的预期结果是程序在最后时间打印后终止,而不是 1 分钟终止。

感谢大家的时间和帮助!

最佳答案

您需要调用 shutdown-agents 最后停止 Clojure 的线程池。

另见 Agents and Asynchronous Actions在 clojure.org 上:

Note that use of Agents starts a pool of non-daemon background threads that will prevent shutdown of the JVM. Use shutdown-agents to terminate these threads and allow shutdown.

关于multithreading - 在 Clojure 中使用 pmap 来并行化归并排序。程序在结束前挂起约 1 分钟,然后终止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55788380/

相关文章:

java - 停止阵列中正在运行的线程

ios - 如何使用 GCD 进行资源的轻量级事务锁定?

java - 请解释以下代码的作用?

emacs - 使用 Emacs Starter Kit 时禁用 Emacs 中的 hl-line?

eclipse - 如何在 Eclipse 中重新缩进所有代码?

clojure - 如何在 Clojure 中创建可调用对象?

java - 说一个列表在内部被锁定是什么意思?

Java - 运行一个线程两次

c# - 合并回调

java - 并发 - 为什么会出现这种死锁