[Prev][Next][Index][Thread]
Re: Passing parameters to threads
Dustin Voss wrote:
> In article
> <Pine.GSO.3.96.1000413170453.4171D-100000@tardis.tardis.ed.ac.uk>, Hugh
> Greene <q@tardis.ed.ac.uk> wrote:
>
> > On Thu, 13 Apr 2000, Dustin Voss wrote:
> > > What is the best practice to pass a parameter to a thread? The thread
> > > function passed to make(<thread>) looks like it takes no parameters.
> >
> > That's correct, the thread function has to take no parameters; and,
> > strictly speaking, you don't "pass parameters to" a thread, since it isn't
> > called. But, to be helpful rather than pedantic [:)], what you do is use
> > closures; i.e., you mention inside a "method ... end" a binding which
> > occurs outside its scope ("further up").
>
> Huh...closures...Never wudda thunk it. Thanks!
It may simpler to just define a thread variable like:
define thread variable *thread-state* = #f;
and then use the with-dynamic-binding macro (I hope I got the name right):
with-dynamic-binding(*thread-state* = get-my-state())
....
end;
(details may be wrong)
Roman
>
>
> [not snipping for posterity's sake]
>
> > So instead of
> >
> > make(<thread>,
> > function: do-something-with /* how do I pass 'my-state'?! */ );
> >
> > you want to say
> >
> > let my-state = get-some-state();
> > make(<thread>,
> > function:
> > method ()
> > do-something-with(my-state)
> > end);
> >
> > [And I'm opening myself up to pedantry, since I'm not sure I have the
> > "function:" keyword right ;-)]
> >
> >
> > Note that there's a real gotcha here if your state is closed over a
> > thread-local variable. If you say
> >
> > define thread variable *my-state* = #f;
> >
> > // Later ...
> > *my-state* := get-some-state();
> > make(<thread>,
> > function:
> > method ()
> > do-something-with(*my-state*)
> > end);
> >
> > then do-something-with will be called with the value of *my-state* _in the
> > new thread_, i.e., #f (or it might even be undefined, I can't remember)!
> > The workaround is to make a new, non-thread-local binding to the value
> > first, then "close over" that:
> >
> > define thread variable *my-state* = #f;
> >
> > // Later ...
> > *my-state* := get-some-state();
> > // This next binding isn't thread-local
> > let non-thread-local-my-state = *my-state*;
> > make(<thread>,
> > function:
> > method ()
> > do-something-with(non-thread-local-my-state)
> > end);
> >
> > This is a pretty evil gotcha -- I'm sure it popped up in code in FD, back
> > when it was HD, and it took us a while to spot -- but it very nicely
> > illustrates closures and how "bindings are like pointers/references" (in
> > that we have thread-local *bindings*, not thread-local state).
> >
> > Hope that helps,
> > Hugh
Follow-Ups:
References: