multithreading-problem

Scott David Daniels Scott.Daniels at Acm.Org
Sun Jul 27 16:29:38 EDT 2003


Diez B. Roggisch wrote:
> ...
> for i in xrange(4):
>   thread = threading.Thread(target=lambda : foo(i))
>   thread.start()
> ... So it appears that the curried lambda passed as target is 
 > somehow a reference equal for all four invocations....
This is why the "curry" recipe dances more jig than you have.
the lambda-expression that you've passed in did not do any
value-capture.  The smallest fix is:
 > ...
 > for i in xrange(4):
 >   thread = threading.Thread(target=lambda v=i: foo(v))
 >   thread.start()
 > ...

With curry from the Python Cookbook (or as below), I'd write:
 > ...
 > for i in xrange(4):
 >   thread = threading.Thread(target=curry(foo, i))
 >   thread.start()
 > ...

The problem is that your lambda expression looks up "i" at function
evaluation time (when target is called), not when you assign the
target function for the thread.

-Scott David Daniels
Scott.Daniels at Acm.Org


=============================
for 2.2 I define curry as:

from __future__ import nested_scopes

def curry(*_args, **_kwargs):
     """curry(f,<args>)(<more>) == f(<args>, <more>) (roughly).

     keyword args in the curry call can be overridden by keyword args
     in the later call; curry can be used to change defaults.
     """
     def result(*__args, **__kwargs):
         if _kwargs and __kwargs:
             kwargs = _kwargs.copy()
             kwargs.update(__kwargs)
         else:
             kwargs = _kwargs or __kwargs
         return _args[0](*(_args[1:]+__args), **kwargs)
     return result





More information about the Python-list mailing list