[Prev][Next][Index][Thread]

Re: Passing parameters to threads



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").

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: