Jump to content

Dining philosophers: Difference between revisions

→‎{{header|Clojure}}: fixed typos in code; also format as clojure
(→‎{{header|Oz}}: Removed unused helper function)
(→‎{{header|Clojure}}: fixed typos in code; also format as clojure)
Line 293:
=={{header|Clojure}}==
Clojure's STM allows us to avoid low-level synchronization primitives like semaphores. In order to simulate the Dining Philosophers scenario, the forks are [http://clojure.org/refs references] to a boolean indicating whether or not it is available for use. Each philosopher (also held in a ref) has a fixed amount of food he will try to eat, first by trying to acquire both forks, eating for some period of time, releasing both forks, then thinking for some period of time; if the forks cannot be acquired, the philosopher waits for a fixed amount of time and tries again.
<lang lispclojure>(defn make-fork []
(ref true))
 
Line 324:
(Thread/sleep retry-interval))))</lang>
The second line of the <tt>start-eating</tt> function contains the essential solution: by invoking <tt>ensure</tt> on every fork reference, we are guaranteed that the state of the forks will not be modified by other transactions, thus we can rely on those values for the rest of the transaction. Now we just need to run it:
<lang lispclojure>(def *forks* (cycle (take 5 (repeatedly #(make-fork)))))
 
(def *philosophers*
(doall (map #(make-philphilosopher %1 [(nth *forks* %2) (nth *forks* (inc %2))] 1000)
["Kant" "Jasay" "Locke" "Nozick" "Rand"]
(range 5))))
 
(defn start []
(doseq [phil * philosophers*]
(.start (Thread. #(dine phil 5 100 100)))))
 
Line 339:
(doseq [i (range 5)]
(let [f @(nth *forks* i)
p @(nth *philsphilosophers* i)]
(println (str "fork: available=" f))
(println (str (:name p)
Anonymous user
Cookies help us deliver our services. By using our services, you agree to our use of cookies.