RosettaCodeData/Task/Dining-philosophers/Clojure/dining-philosophers-1.clj

31 lines
896 B
Clojure

(defn make-fork []
(ref true))
(defn make-philosopher [name forks food-amt]
(ref {:name name :forks forks :eating? false :food food-amt}))
(defn start-eating [phil]
(dosync
(if (every? true? (map ensure (:forks @phil))) ; <-- the essential solution
(do
(doseq [f (:forks @phil)] (alter f not))
(alter phil assoc :eating? true)
(alter phil update-in [:food] dec)
true)
false)))
(defn stop-eating [phil]
(dosync
(when (:eating? @phil)
(alter phil assoc :eating? false)
(doseq [f (:forks @phil)] (alter f not)))))
(defn dine [phil retry-interval max-eat-duration max-think-duration]
(while (pos? (:food @phil))
(if (start-eating phil)
(do
(Thread/sleep (rand-int max-eat-duration))
(stop-eating phil)
(Thread/sleep (rand-int max-think-duration)))
(Thread/sleep retry-interval))))