I'm trying to call 2 functions in parallel using the python 2.7 threading module, and, to make things easier for myself, I've written my own AsycTask
class.
class AsyncTask:
def __init__(self, task, name="async-task", callback=None):
self.task = task
self.t = None
if self.task is not None:
if callback is not None:
self.t = threading.Thread(target=lambda: [task(), callback()], name=name)
else:
self.t = threading.Thread(target=self.task, name=name)
def start(self):
if self.t is not None:
self.t.start()
else:
Log.warn("Can't start async task: thread is None")
def join(self):
if self.t is not None:
self.t.join()
else:
Log.warn("Can't join async task: thread is None")
But I get some strange results when I pass it function handles.
Elsewhere I have this class:
class Foo:
def __init__(self, id):
self.id = id
def bar(self, args):
result = None
# do some stuff that takes a while
time.sleep(10)
Log.debug("bar() called in object %s" % self.id)
return result
Then I create a list of foo's
foos = []
foos.append(Foo("1"))
foos.append(Foo("2"))
And call bar
asynchronously
results = []
tasks = []
for foo in foos:
args = "some stuff"
fn = foo.bar
Log.debug("before async: " + str(foo))
task = AsyncTask(lambda: [Log.debug("in async: " + str(fn)), results.append(fn(args))])
tasks.append(task)
task.start()
for task in tasks:
task.join()
# process results
When I run this I get:
before async: <__main__.Foo instance at 0x7f9caef7e200>
before async: <__main__.Foo instance at 0x7f9caef7e248>
in async: <bound method Foo.bar of <__main__.Foo instance at 0x7f9caef7e248>>
in async: <bound method Foo.bar of <__main__.Foo instance at 0x7f9caef7e248>>
bar() called in object 2
bar() called in object 2
Note that bar()
on the first Foo
instance is never called, while it is called twice on the second instance.
I don't have a ton of python experience, so clearly, I am doing something wrong and must not properly understand how threading and function handles work in python.
What would a more pythonic way be to accomplish this?