send versus send-off

107 views
Skip to first unread message

Kai

unread,
Jun 30, 2009, 5:30:34 PM6/30/09
to Clojure
I can't imagine that this hasn't been asked before, so please direct
this post to an appropriate link if you know of it.

(send a f & args)
Dispatch an action to an agent. Returns the agent immediately.
Subsequently, in a thread from a thread pool, the state of the agent
will be set to the value of:

(send-off a f & args)
Dispatch a potentially blocking action to an agent. Returns the agent
immediately. Subsequently, in a separate thread, the state of the
agent will be set to the value of:

Why is there a distinction between an action and a blocking action?
What kind of concerns arise when you send a potentially blocking
action to an agent and why is send-off better accommodated to deal
with it?

From scheduling I know that there are CPU-bound and IO-bound
processes. Perhaps send-off tends to hold off on yielding for longer
durations since it expects frequent interrupts. If this is the case, I
think it would be useful to elaborate on that in the documentation of
send-off, even if that's something implemented mostly in Java.

~ Kai

Meikel Brandmeyer

unread,
Jun 30, 2009, 5:52:35 PM6/30/09
to clo...@googlegroups.com
Hi,

Am 30.06.2009 um 23:30 schrieb Kai:

> Why is there a distinction between an action and a blocking action?
> What kind of concerns arise when you send a potentially blocking
> action to an agent and why is send-off better accommodated to deal
> with it?

send serves the agent from a fixed ThreadPool. When all
threads in this ThreadPool are used up, your agents basically
freeze waiting in a queue for free threads. The number of threads
in this ThreadPool is limited. send'ing a blocking action basically
blocks the thread. Enough blocking threads might use up all
threads and there you go.

send-off allocates a new thread in a different ThreadPool.
So the aforementioned scenario cannot happen.

A Guru might want to give the details of the second scenario.

Sincerely
Meikel

Stephen C. Gilardi

unread,
Jun 30, 2009, 6:39:05 PM6/30/09
to clo...@googlegroups.com

On Jun 30, 2009, at 5:30 PM, Kai wrote:

> From scheduling I know that there are CPU-bound and IO-bound
> processes. Perhaps send-off tends to hold off on yielding for longer
> durations since it expects frequent interrupts. If this is the case, I
> think it would be useful to elaborate on that in the documentation of
> send-off, even if that's something implemented mostly in Java.


-------------------------

send-off:
- is the more general case
- is somewhat slower on average
- has a quiescent thread count of 0
- has a transient thread count that can be arbitrarily high
- accommodates actions that block.

send-off uses a cached thread pool. The pool grows as necessary to
accommodate new high water marks of simultaneously pending actions.
When an action completes, the thread that ran it is kept around for a
time for possible reuse. If a thread remains idle for a significant
amount of time, it's terminated and released. The current Java
implementation of Clojure uses a cached thread pool as described here:

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Executors.html#newCachedThreadPool%28%29

-------------------------

send:
- is an optimization for non-blocking actions
- is somewhat faster on average
- has a fixed thread count whether it's being used or not
- fails to operate properly if used with actions that block.

send uses a fixed cache pool whose size is related to the number of
processors (cores) that the JVM sees on your machine. The threads are
created when Clojure starts up and are not released. They take actions
off of a shared queue. send never incurs the overhead of creating a
thread. The promise is (roughly) that your action either executes
(close to) immediately or waits on a queue because all of the
available cores are busy anyway. Blocking one of the fixed pool's
threads would be bad and works against fulfilling send's promise. The
current Java implementation of Clojure uses a fixed thread pool as
described here:

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool%28int%29

--Steve

Kai

unread,
Jul 1, 2009, 10:36:33 AM7/1/09
to Clojure
Thanks Meikel and Steve it is quite clear now! I will redirect
questions here should anybody ask.

~ Kai
Reply all
Reply to author
Forward
0 new messages