[Openmcl-devel] Thread-local bindings
ron at flownet.com
Sat Jun 15 13:48:24 PDT 2019
On Jun 15, 2019, at 1:14 PM, martin <brooks.martin at sympatico.ca> wrote:
> Thanks; I stand corrected on both counts.
> I am guessing the last call to process-run-function is supposed to have :thread-3 throughout.
Um, yeah, sorry about that.
> Assuming this is so, what I see is:
> THREAD1 GLOBAL-FOO 1
> MAIN-THREAD GLOBAL-FOO 2
> THREAD2 THREAD-2-FOO 3
> THREAD3 THREAD-3-FOO 1
> THREAD1 GLOBAL-FOO 4
> MAIN-THREAD GLOBAL-FOO 5
> THREAD2 THREAD-2-FOO 6
> THREAD3 THREAD-3-FOO 2
> THREAD1 GLOBAL-FOO 7
> MAIN-THREAD GLOBAL-FOO 8
> THREAD2 THREAD-2-FOO 9
> THREAD3 THREAD-3-FOO 3
> Thread-1, thread-2 and main-thread take turns incrementing the global binding of *cnt*, whereas thread-3 increments its local binding.
> So, yes — the global binding is shared across the top level — was that your point?!?
“Top level” is not really a well defined concept. The global binding is shared among all threads that don’t have a thread-local binding.
> I am looking for words; perhaps this is better:
> The dynamic extent of special lambda bindings has no meaning except in the thread that established those bindings.
> The point upon which I initially hit my head was the case where a new thread is launched from within the extent of such special lambda bindings.
> Those bindings have no meaning for the new thread.
This is implementation dependent. The CL standard does not talk about threads at all, so it doesn’t talk about what happens when a thread is launched.
This is one of the design decisions that a Lisp implementation needs to make: when a new thread is launched, does it inherit the thread-local bindings of the thread that launched it or not?
CCL actually lets the user decide, though it does not expose this in the API for process-run-function. You have to go to a lower level if you want to control this. Look at the documentation for MAKE-PROCESS, specifically the INITIAL-BINDINGS and USE-STANDARD-INITIAL-BINDINGS arguments.
> Except … unless the new thread’s function is specially designed to promulgate those bindings, so that code in the new thread proceeds in the dynamic context of the parent thread:
> (process-run-function :my-thread #’(lambda (special-var) …) special-var)
That lets you *create* a thread-local binding, but you can’t *inherit* one that way.
BTW, if you’re playing around with this you should also look at the function SYMBOL-VALUE-IN-PROCESS. It’s not documented, but it just does exactly what the name implies: gives you the current value of a thread-local binding for a particular thread/process regardless of what thread/process you are actually in at the time.
More information about the Openmcl-devel