Threading có thể sẽ là giải pháp đơn giản nhất, nhưng nó không phải là rất khó khăn để quản lý nó bản thân trên một chủ đề duy nhất. Môi trường "Mô phỏng" chỉ cung cấp cho bạn 100ms thường không cho phép bất kỳ chủ đề mới nào, vì vậy đây là một thay thế.
Ý tưởng cơ bản là tạo ra một đóng cửa đại diện cho những công việc cần phải làm để hoàn thành nhiệm vụ, và trở về mà thay vì vậy nếu bạn không có thời gian để kết thúc. Dưới đây là một phác thảo: nó thêm một chuỗi các con số lên, và bị gián đoạn mỗi mười hoạt động thay vì mỗi 100ms.
(let [timer (atom 9)]
(defn keep-going? []
(not= 0 (swap! timer #(mod (inc %) 10)))))
(defn saving-addition [sum xs]
(if-let [[x & more] (seq xs)]
(let [next-thunk (fn [] (saving-addition (+ x sum) more))]
(if (keep-going?)
(next-thunk)
next-thunk))
sum))
(defn monitor [xs]
(loop [thunk (saving-addition 0 xs)]
(if (fn? thunk)
(do
(println "Saving execution state")
(recur (thunk)))
thunk)))
user> (monitor (range 25))
Saving execution state
Saving execution state
Saving execution state
300
Chỉnh sửa: Do Clojure không có tối ưu hóa cuộc gọi đuôi, tạo một đoạn và sau đó gọi nó sử dụng hết ngăn xếp. Nếu, có khả năng, bạn có thể thực hiện nhiều hơn một vài nghìn bước trước khi bạn cần phải bị gián đoạn, bạn sẽ nhận được tràn ngăn xếp. Các giải pháp thực tế duy nhất là để lặp lại trong cơ thể của thunk trong cả một recur
và trong việc tiếp tục, như
(defn saving-addition [sum xs]
(if-let [[x & more] (seq xs)]
(let [sum (+ x sum)]
(if (keep-going?)
(recur sum more)
#(saving-addition sum more)))
sum))
Bạn có thể có thể trừu tượng này ra với một macro nếu bạn phải viết nhiều như vậy chức năng "suspendable".
cây không được sắp xếp? Bạn chỉ cần tìm một số phần tử và trả về true nếu bạn nhận được nó, hoặc bạn cũng cần đường dẫn? – toto2