At ELS Vladimir mentioned that he doesn't intend to add a THREAD-JOIN
primitive because joinable threads incur a performance penalty. How is
that so ?
Stelian Ionescu a.k.a. fe[nl]ix
Quidquid latine dictum sit, altum videtur.
From: Vladimir Tzankov <vtzankov@gm...> - 2009-06-10 23:10:29
On 6/10/09, Stelian Ionescu <stelian.ionescu-zeus@...> wrote:
> At ELS Vladimir mentioned that he doesn't intend to add a THREAD-JOIN
> primitive because joinable threads incur a performance penalty. How is
> that so ?
There are at least two reasons I do not want to implement thread-join.
POSIX pthread_join() incur possibilities for resource leaks and
undefined behavior. If joinable thread is not actually joined it
becomes so called "zombie" thread. see notes on:
By using only detached threads we do not have these issues. If you say
that users should take care about such cases - I do not agree. With
provided primitives - joinable threads can be implemented if really
needed. Trivial generic implementation is something like this (ugly
and not thoroughly tested):
(defun make-joinable-thread (function)
(let ((mstarted (make-mutex :name "ack the thread owns join-mutex"))
(estarted (make-exemption :name "signal the thread got the mstarted"))
(join-mutex (make-mutex :name (format nil "join mutex of ~A" function)))
(make-thread (lambda ()
(setf thread-started t)
(exemption-signal estarted) ; signal we are
(mutex-lock join-mutex) ; wait to start
(mutex-unlock mstarted) ; ack we got the join-mutex
(loop while (not thread-started) do ; there may be spurious wake-ups
(exemption-wait estarted join-mutex))
(mutex-unlock join-mutex) ; let the thread run
(mutex-lock mstarted) ; be sure thread has the join -lock
(values thread join-mutex)))))
You may wait with MUTEX-LOCK on the second return value (if any) for
thread-join behavior. All the ugliness in the above function is to
ensure that before we return - join-mutex is owned by the spawned
Depending on the application domain this can be more elegant and it is
up to the user to do so - there is no reason to impose the "right" way
for such cases, IMHO.
Second reason not to implement thread-join is that there is no way (at
least I am not aware of) to interrupt it safely with arbitrary lisp
code (incl. non-local exit) i.e. thread-kill, thread-interrupt, ctrl-c
and call-with-timeout if we wait inside pthread_join() cannot be
implemented in POSIX compliant way.
>From design point of view - I do not thing it is good idea to spawn
threads all the time and join on them. Thread creation is expensive. I
prefer to have long time running threads.