[Openmcl-devel] Thread-local bindings

martin 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.

Martin


> 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.
> 
> rg
> 




More information about the Openmcl-devel mailing list