2 Nov 2009 23:16
Re: mt question/problem
Don Cohen <don-sourceforge-xxz <at> isis.cs3-inc.com>
2009-11-02 22:16:29 GMT
2009-11-02 22:16:29 GMT
I begin to understand - this all seems to be related to the
implementation choice to use a "shallow binding" scheme.
It seems to me that the "deep binding" scheme has the "obviously
correct" semantics (meaning, what seems obvious to me, but of course
the semantics of lisp was never really defined for multiple threads).
Shallow binding was a clever optimization of deep binding that works
only in a single threaded environment.
I think you're now trying to use shallow binding but changing the
semantics of special variables. This is also not entirely clear from
the doc.
32.5.2.2. Special Variable Values
Every dynamic variable has a global value that can be shared across
all MT:THREADs.
Bindings of dynamic variables (via LET/LET*/MULTIPLE-VALUE-BIND) are
local to MT:THREADs, i.e. every SYMBOL has a different value cell in
each MT:THREAD. MT:SYMBOL-VALUE-THREAD can be used to inspect and
modify these thread local bindings.
Here I would have expected
(let (c) (declare (special c)) (foo))
to qualify under the above "Bindings of dynamic variables".
One might argue that the very fact that CLHS defines symbol-value
seems to require something like shallow binding, but it strikes me
that it might also be consistent with CLHS to make symbol-value depend
implicitly on (current-thread). And this would better preserve the
semantics of special variables.
The statement above that every dynamic variable has a global value
could still make sense, but then I'd expect to access that not by
symbol-value, but by a newly invented global-symbol-value. But I also
don't see that such a global value is necessary.
Vladimir Tzankov writes:
> > What's the difference between a global special and any other kind?
> defparameter, defvar and proclaimed specials cause per value cell to
Could you possibly mean "per thread value cell"?
> be allocated for symbols. Special variables may have different
> bindings in different threads.
I certainly expect that special variables should be able to have
different values in different threads, but I'd expect this to be
true whether they are proclaimed (or is that now "declaimed"?) special
or only declared special as in (let (c) (declare (special c)) (foo)).
So defvar and defparameter create what you call "global" specials?
But (declare (special ...)) does not, right?
I'm now guessing that (let (x)(declare (special x))...) uses "the
global" value cell in the the symbol x rather than a cell for x in the
current thread. This violates my intuition/understanding of what
special variables are all about. Can you see any justification for
such semantics other than ease of implementation?
> > How does :initial-bindings compare to something like
> > (let ((vars '(a b c))(vals (list a b c)))
> > (mt:make-thread
> > (lambda ()
> > (progv vars vals ...))))
> If A, B and C are not special variables they will not have per thread
> allocated value cells - bindings that progv will establish will be
> shared between all threads (values of A,B and C in all threads will be
> the same).
Progv variables are all special. I think what you mean is that,
because they're not "globally" special (meaning globally declared to
be), they won't act like special variables here.
> Note also that vars and vals values will be shared between two threads
> (in case above it's not important) - in order to avoid this (let
> ((vars vars) (vals vals)) (mt:make-thread ...)) may be used.
I guess you mean if I had done two different make-thread's in the same
(let ((vars ...)(vals ...)) ...)
Vladimir Tzankov writes:
> On 11/2/09, Don Cohen <don-sourceforge-xxz <at> isis.cs3-inc.com> wrote:
> > How does :initial-bindings compare to something like
> > (let ((vars '(a b c))(vals (list a b c)))
> > (mt:make-thread
> > (lambda ()
> > (progv vars vals ...))))
>
> The main difference is that forms in initial-bindings are eval-ed in
> the context of newly created thread.
Whoa!! This is even more unexpected! Was that in the doc somewhere?
(Of course, in my example I arranged to evaluate things in the calling
thread and then quote them so it didn't matter where the evaluation
was done.)
It seems to me that the current design makes it unnecessarily
difficult to pass arguments to the new thread. I'd really like to do
something more like
(make-thread {optional keyword args if necessary} function . args)
where args are evaluated before the thread is created and the values
are then given as arguments to the function in the new thread.
> ... Thus any reference to thread
> specific data (mt:current-thread, mutex ownership change, deferred
> interrupts ..) are specific to new thread. Evaluation of these forms
> is performed before just before funcall-ing the thread lambda.
So far I'm having trouble seeing when/why it's useful to do that
evaluation in the new thread.
I am seeing that this makes it difficult to pass info from the old
thread to the new one. For instance, I had tried to use initial
bindings to use the same package in the new thread as in the old one,
but it now appears that the "obvious" way of doing this would have
failed.
> Main purpose of initial-bindings is to perform initialization of some
> global data that should not be shared between threads -
> *random-state*, *readtable*, *defer-interrupts*, etc - not for passing
So far I don't see why it's important not to share the random state.
It looks to me like you're really just trying to avoid locking it.
Most of the other things in *DEFAULT-SPECIAL-BINDINGS* seem
unnecessary or worse, e.g., *print-base* - shouldn't the default be
whatever I set the "global" value to?
> "arguments" to thread function - see *DEFAULT-SPECIAL-BINDINGS* in
> threads.lisp.
> When you use initial-bindings it's best to cons your specific data in
> front of *DEFAULT-SPECIAL-BINDINGS* or copy and modify it to fit your
> needs.
------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
clisp-devel mailing list
clisp-devel <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/clisp-devel
RSS Feed