Использование pmap в Clojure для распараллеливания сортировки слиянием.Программа зависает в конце на ~ 1 минуту, перед завершением - PullRequest
1 голос
/ 22 апреля 2019

Я пишу программу на Clojure, которая принимает данные из текстового файла 10000.txt (в нем 10k целых чисел без знака). Затем я передаю этот список в мои функции сортировки слиянием (поток sigle, 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 минуту напрекратить.

Спасибо всем за ваше время и помощь в этом!

1 Ответ

7 голосов
/ 22 апреля 2019

Вам нужно позвонить shutdown-agents в конце, чтобы остановить пул потоков Clojure.

Также см. Агенты и асинхронные действия на clojure.org:

.

Обратите внимание, что использование Агентов запускает пул фоновых потоков, не являющихся демонами, которые будут препятствовать завершению работы JVM. Используйте shutdown-agent для завершения этих потоков и разрешения завершения работы.

...