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