This really seems like a good use case for Java's Executors: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool(int)
You can specify the number of worker threads, then enqueue runnable jobs. But wait! There's more! Clojure functions implement Runnable, so you can just hand a zero argument function to the service once you create it: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html#submit(java.lang.Runnable) On Tue, Aug 23, 2016 at 7:09 AM, <adrian.med...@mail.yu.edu> wrote: > I haven't run your code yet, but it's bad form to use Clojure's reference > types inside other reference types. They should store persistent data > structures to really make any sense in a concurrent context. > > On Tuesday, August 23, 2016 at 8:22:00 AM UTC-4, Sergei Koledov wrote: > >> Hello, >> >> I had a problem when I run the following code: >> >> (defn get-task [tasks] >> (dosync >> (let [task (first @tasks)] >> (alter tasks rest) >> task))) >> >> (defn worker [& {:keys [tasks]}] >> (agent {:tasks tasks})) >> >> (defn worker-loop [{:keys [tasks] :as state}] >> (loop [last-task nil] >> (if-let [task (get-task tasks)] >> (recur task) >> (locking :out (println "Last task: " last-task)))) >> state) >> >> (defn create-workers [count & options] >> (->> (range 0 count) >> (map (fn [_] (apply worker options))) >> (into []))) >> >> (defn start-workers [workers] >> (doseq [worker workers] (send-off worker worker-loop))) >> >> (def tasks (ref (range 1 10000000))) >> >> (def workers (create-workers 100 :tasks tasks)) >> >> (start-workers workers) >> (apply await workers) >> >> Description: I have several agents (100 in my case). Each agent running >> in a separate thread. All agents share the one ref with the collection of >> tasks (range of longs in my case). Each agent get tasks from the collection >> (in transaction) one by one until the collection becomes empty and then >> prints the last task which it handle. However, when I run this code it >> looks like the collection of tasks suddenly becomes empty and workers >> handle only portion of all tasks (average 25-40% of all number). >> >> This code behave as I expected, when I create only one agent or use >> explicit locking in get-task function: >> >> (defn get-task [tasks] >> (locking :lock >> (dosync >> (let [task (first @tasks)] >> (alter tasks rest) >> task)))) >> >> I run this code on the Clojure 1.8.0 >> java version "1.8.0_91" >> Java(TM) SE Runtime Environment (build 1.8.0_91-b14) >> Java HotSpot(TM) 64-Bit Server VM (build 25.91-b14, mixed mode) >> >> Can anyone tell me, what am I doing wrong, or it really looks like a bug >> in the clojure STM? >> I already asked this question on stackoverflow.com ( >> http://stackoverflow.com/questions/39054911/strange-behavio >> r-of-clojure-ref), but so far nobody has been able to help me. >> >> P.S. Sorry for my english skill. >> > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- “One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs.” (Robert Firth) -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.