Multithreading Python将函数句柄传递给线程
我试图使用Python2.7线程模块并行调用两个函数,为了让事情变得更简单,我编写了自己的Multithreading Python将函数句柄传递给线程,multithreading,python-2.7,asynchronous,Multithreading,Python 2.7,Asynchronous,我试图使用Python2.7线程模块并行调用两个函数,为了让事情变得更简单,我编写了自己的AsycTask类 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 No
AsycTask
类
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")
但当我传递函数句柄时,会得到一些奇怪的结果
在其他地方,我有这门课:
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
然后我创建一个foo的列表
foos = []
foos.append(Foo("1"))
foos.append(Foo("2"))
并异步调用bar
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
当我运行此命令时,我得到:
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
异步之前的:
异步之前:
在异步模式下:
在异步模式下:
在对象2中调用了bar()
在对象2中调用了bar()
请注意,第一个Foo
实例上的bar()
我没有太多的python经验,所以很明显,我做错了什么,不能正确理解python中线程和函数句柄是如何工作的
有什么比python更适合的方法来实现这一点呢?您的设置类很好,我们看不到的奇怪行为的原因很可能是您如何设置记录器。我得到了与您相同的行为,直到我按照如下方式设置了记录器:
import logging
logging.basicConfig()
log = logging.getLogger('log')
之后,我得到以下信息:
before async: <__main__.Foo instance at 0x00000000028C9FC8>
before async: <__main__.Foo instance at 0x00000000028D5048>
<__main__.Foo instance at 0x00000000028C9FC8>
<__main__.Foo instance at 0x00000000028D5048>
异步之前的:
异步之前:
谢谢您的快速回复,但我不相信。在我的实际设置中,Foo
是一些硬件的接口,bar()
肯定只在一个实例上被调用。我编辑了我的问题,在'Foo'中添加了一个id
类成员,以更好地说明问题。这与线程无关;使用fn
作为结束语传递lambda
是一个问题。@MartijnPieters您能详细说明或链接到一些关于您的意思的信息吗?什么是更好的解决方案?我关闭了这篇文章作为一个副本,请参阅另一篇文章,其中概述了几个选项。啊,这很有帮助。非常感谢。