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.

Reply via email to