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