Thank you! I know about Java's thread pools, but I want to do my job in clojure-idiomatic way and possibly less using java interop.
вторник, 23 августа 2016 г., 20:21:23 UTC+7 пользователь tbc++ написал: > > 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...@mail.yu.edu <javascript:>> > 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-behavior-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 clo...@googlegroups.com >> <javascript:> >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+u...@googlegroups.com <javascript:> >> 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+u...@googlegroups.com <javascript:>. >> 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.