Excellent, very nice.  Mind if I use it?

jds

On Jan 30, 2:09 am, Timothy Pratley <timothyprat...@gmail.com> wrote:
> Below I present 'submit-future' which is similar to the existing
> 'future' call in that it spawns a thread to execute a task, but
> differs in that it will block if n submitted futures are already
> running, where n is the number of available processors. I think this
> could be quite handy for the producer-consumer model which lazy-seq
> lends itself to, allowing one to write:
>
> (doseq [d data-seq]
>   (submit-future (foo d)))
>
> where data-seq is some feed of CPU bound tasks which you want to
> process as quickly as possible. This is diverging from the OP, but
> thought it might be of interest:
>
> (let [limit (.availableProcessors (Runtime/getRuntime))
>       sem (java.util.concurrent.Semaphore. limit)]
>   (defn submit-future-call
>     "Takes a function of no args and yields a future object that will
>     invoke the function in another thread, and will cache the result and
>     return it on all subsequent calls to deref/@. If the computation has
>     not yet finished, calls to deref/@ will block.
>     If n futures have already been submitted, then submit-future blocks
>     until the completion of another future, where n is the number of
>     available processors."
>     [#^Callable task]
>     ; take a slot (or block until a slot is free)
>     (.acquire sem)
>     (try
>       ; create a future that will free a slot on completion
>       (future (try (task) (finally (.release sem))))
>       (catch java.util.concurrent.RejectedExecutionException e
>         ; no task was actually submitted
>         (.release sem)
>         (throw e)))))
>
> (defmacro submit-future
>   "Takes a body of expressions and yields a future object that will
>   invoke the body in another thread, and will cache the result and
>   return it on all subsequent calls to deref/@. If the computation has
>   not yet finished, calls to deref/@ will block.
>   If n futures have already been submitted, then submit-future blocks
>   until the completion of another future, where n is the number of
>   available processors."
>   [& body] `(submit-future-call (fn [] ~...@body)))
>
> #_(example
>     user=> (submit-future (reduce + (range 100000000)))
>     #<core$future_call$reify__5...@6c69d02b: :pending>
>     user=> (submit-future (reduce + (range 100000000)))
>     #<core$future_call$reify__5...@38827968: :pending>
>     user=> (submit-future (reduce + (range 100000000)))
>     ;; blocks at this point for a 2 processor PC until the previous
>     ;; two futures complete
>     #<core$future_call$reify__5...@214c4ac9: :pending>)

-- 
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

Reply via email to