[Openmcl-devel] Thread-local bindings
brooks.martin at sympatico.ca
Sat Jun 15 14:07:33 PDT 2019
Those are very useful pointers … thanks !
I am playing with my inheritance-by-shadowing scheme just now, and there are nuisance factors with always shadowing the actual bindings; sometimes I want to inherit and sometimes shadow.
The CCL documentation say that USE-STANDARD-INITIAL-BINDINGS is deprecated and dangerous to the implementation.
Are there any details for that?
One implementation problem I can imagine for providing inherited thread-local bindings is that the parent thread can finish before the child.
Assuming the dynamic binding is on the parent thread’s stack, this sounds like trouble !
Or the parent is still running, and it returns from the dynamic environment in which child was launched while the child is still running.
Hmm … some schemes come to mind, but could be tricky …
In fact, I don’t have that sort of problem — I typically spawn multiple threads in order to parallelize mapcar, and the parent thread waits for the children to finish.
> On Jun 15, 2019, at 4:48 PM, Ron Garret <ron at flownet.com> wrote:
> 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