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