线程在调用Thread.start之前就开始运行了。

27
t1=threading.Thread(target=self.read())
print("something")
t2=threading.Thread(target=self.runChecks(), args=(self,))

self.read 会一直运行,所以程序永远不会到达 print 行。没有调用 t1.start() 怎么可能实现这一点呢?(即使我调用了它,它也应该开始运行并继续执行下一行,不是吗?)


请参阅:当函数调用中省略括号(假设不需要参数)时是什么意思? 以深入了解此错误,并查看Python参数绑定器获取更通用的解决方案。

1个回答

46
由于 target=self.read() 后面有一个尾随的 (),你正在错误的线程——当前线程中运行 self.read,而不是你创建的新线程,并将 self.read 调用的返回值作为 Threadtarget 参数传递。 Thread 期望被传递一个要调用的函数,因此只需删除括号并记得启动线程即可:
t1=threading.Thread(target=self.read)
t1.start()
print("something")

对于需要参数的目标,您可以使用argskwargs参数来调用threading.Thread,或者您可以使用lambda表达式。例如,要在线程中运行f(a, b, x=c),您可以使用以下代码:
thread = threading.Thread(target=f, args=(a, b), kwargs={'x': c})

或者

thread = threading.Thread(target=lambda: f(a, b, x=c))

尽管如此,如果您选择lambda,请注意lambda将在使用时查找f、a、b和c,而不是在定义lambda时查找,因此如果在线程被调度之前重新分配任何这些变量,则可能会获得意外结果(即使立即调用start,调度线程可能需要任意长时间)。

天啊,希望所有的教程都能提到这个!https://www.quantstart.com/articles/parallelising-python-with-threading-and-multiprocessing/ - TCSGrad
@TCSGrad 是的,那里的代码确实是有问题的。我也希望这个世界不会充满糟糕的教程,但这是我们为自由付出的代价之一。 - Karl Knechtel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接