Python线程:是否并行计算传递给线程的参数?
我在python中有一个函数调用,如下所示:Python线程:是否并行计算传递给线程的参数?,python,multithreading,Python,Multithreading,我在python中有一个函数调用,如下所示: from threading import Thread while queue: Thread(target=queue.extend, args=(longfunction(a, b))).start() 因此,我认为上面的代码并行运行多个queue.extend函数,即在启动下一个queue.extend之前,它不会等到上一个queue.extend返回。但我不确定这些论点 我的问题是,Python是等到longfunction(a,b
from threading import Thread
while queue:
Thread(target=queue.extend, args=(longfunction(a, b))).start()
因此,我认为上面的代码并行运行多个queue.extend函数,即在启动下一个queue.extend之前,它不会等到上一个queue.extend返回。但我不确定这些论点
我的问题是,Python是等到longfunction(a,b)完成计算并返回后才开始启动新线程,还是整个线程立即启动,然后在longfunction返回之前启动下一个线程
我对线程有点陌生,所以请解释一切 线程构造函数只是一个普通的函数调用;它的所有参数,包括
args
元组,在调用之前都必须求值
因此,这是在主线程中执行long函数(a,b)
,而只在后台线程中执行queue.extend
解决此问题的最快方法是使用def
或lambda
创建线程函数:
Thread(target=lambda: queue.extend(longfunction(a, b)).start()
或者,或者:
Thread(target=(lambda x, y: queue.extend(longfunction(x, y)), args=(a, b)).start()
不同之处在于,第一个是闭包,从本地环境捕获a
和b
,因此,如果在计算lambda时它们发生了变化,您将获得新的值,而第二个不是*,因此它将在创建args元组时获得a
和b
的值。在大多数情况下,这并不重要。当它真的重要时,你必须仔细考虑你想要哪一个
*从技术上讲,闭包和函数在Python中是一样的;它只是一个没有单元格的闭包,而不是一个有两个单元格的闭包。是的,它会在启动线程之前等待它返回。这是因为当您将
()
添加到函数末尾时,它不再是函数引用,而是函数调用。因此,主线程中的args=(longfunction(a,b))
将被计算为args=(return_from_long_函数,)
,然后该值将被传递到线程目标,在这种情况下:queue.extend
,而不使用()
它也不是函数声明(或定义)。只有def
或lambda
创建函数。作为旁注,(longfunction(a,b))
不是元组,它是一个带无意义括号的单个值。构成元组的是逗号,而不是圆括号,因此需要(longfunction(a,b),)
。或者,如果您觉得它更可读,只需使用一个列表:[longfunction(a,b)]
。lambda是否需要将a
和b
作为参数,或者lambda
是否会创建一个捕获它们的闭包?@jpmc26:lambda创建一个捕获它们的闭包。如果要确保它捕获当前值,而不是本地范围中的单元格,则可以使用参数(或默认值参数hack)。(我从来不知道在Python中闭包捕获的东西叫什么;它们不是真正的变量,也不仅仅是名称,但底层闭包单元格对象是一个实现细节,除非您正在编写Python编译器或字节码解释器……)对象引用,可能?(有时称为指针?)除非我弄错了,否则Python确实是按值传递的,但传递的引用值与Java非常相似(尽管在Java中“原语”和“对象”没有区别;一切都是对象)。我相信我在这里找到了一个彻底的讨论:。感谢您的启发。