使用python中的thread.start()返回值(使用队列)

使用python中的thread.start()返回值(使用队列),python,multithreading,queue,Python,Multithreading,Queue,我想创建一个函数的多线程版本。我发现t.start()返回None,所以我必须使用queue。 我搜索了文档,但不知道如何在示例中使用它 这就是功能: def derivative(lst, var): # Example of lst = [1 + [3 * x]] if len(lst) == 1: return derive_solver(lst[0], var) if lst[1] == '+': return [der

我想创建一个函数的多线程版本。我发现
t.start()
返回
None
,所以我必须使用queue。 我搜索了文档,但不知道如何在示例中使用它

这就是功能:

def derivative(lst, var):  # Example of lst =  [1 + [3 * x]]
    if len(lst) == 1:       
        return derive_solver(lst[0], var)

    if lst[1] == '+':
        return [derivative(lst[0], var), '+', derivative(lst[2], var)]

    if lst[1]  == '*':
        return [[derivative(lst[0], var), '*', lst[2]], '+', [lst[0], '*', derivative(lst[2], var)]]
def derivative(lst, var):  # Example of lst =  [1 + [3 * x]]
    if len(lst) == 1:       
        return derive_solver(lst[0], var)

    if lst[1] == '+':
        t1 = threading.Thread(target = derivative,  args=(lst[0], var))
        t2 = threading.Thread(target = derivative,  args=(lst[2], var))
        return [t1.start(), '+', t2.start()]

    if lst[1]  == '*':
        t1 = threading.Thread(target = derivative,  args=(lst[0], var))
        t2 = threading.Thread(target = derivative,  args=(lst[2], var))
        return [[t1.start(), '*', lst[2]], '+', [lst[0], '*', t2.start()]] 
这是我对多线程功能的尝试:

def derivative(lst, var):  # Example of lst =  [1 + [3 * x]]
    if len(lst) == 1:       
        return derive_solver(lst[0], var)

    if lst[1] == '+':
        return [derivative(lst[0], var), '+', derivative(lst[2], var)]

    if lst[1]  == '*':
        return [[derivative(lst[0], var), '*', lst[2]], '+', [lst[0], '*', derivative(lst[2], var)]]
def derivative(lst, var):  # Example of lst =  [1 + [3 * x]]
    if len(lst) == 1:       
        return derive_solver(lst[0], var)

    if lst[1] == '+':
        t1 = threading.Thread(target = derivative,  args=(lst[0], var))
        t2 = threading.Thread(target = derivative,  args=(lst[2], var))
        return [t1.start(), '+', t2.start()]

    if lst[1]  == '*':
        t1 = threading.Thread(target = derivative,  args=(lst[0], var))
        t2 = threading.Thread(target = derivative,  args=(lst[2], var))
        return [[t1.start(), '*', lst[2]], '+', [lst[0], '*', t2.start()]] 
问题是
t1.start(
)不返回值

你知道如何使用队列解决这个问题吗

谢谢大家!

问题是
t1.start()
不返回值

当然不是<代码>t1此时尚未完成。如果
start
等待后台线程完成,那么根本没有理由首先使用线程

您需要设置一些设置,以便后台线程将其工作发布到某个位置,并向您发出完成的信号,然后等待,直到两个线程都向您发出信号。排队是一种方法。共享变量加上
条件也是如此。或者,在这种情况下,只需一个共享变量加上
join
ing线程即可。但我将展示一种使用队列的方法,因为这是您要求的:

def enthread(target, args):
    q = queue.Queue()
    def wrapper():
        q.put(target(*args))
    t = threading.Thread(target=wrapper)
    t.start()
    return q

q1 = enthread(target = derivative,  args=(lst[0], var))
q2 = enthread(target = derivative,  args=(lst[2], var))
return [q1.get(), '+', q2.get()]
我所做的是创建一个队列,将其传递给后台线程的目标函数(它包装了真正的目标函数),并让后台线程将其结果放入队列中。然后,主线程就可以在队列上等待了

请注意,这并不是将每个线程连接起来,这可能是一个问题。但希望您能看到如何扩展代码,使其更加健壮

还要注意,我们显式地等待线程1完成,然后再检查线程2。在一种情况下,你不能做任何事情,直到你有所有的结果无论如何,这是好的。但在许多应用程序中,您需要一个队列,因此可以在结果出现时提取结果(如果需要重建原始顺序,则以某种方式标记值)


更好的解决方案是使用更高级别的抽象,如线程池或未来(或执行器,将两个抽象合并为一个)。但首先要了解这些部件是如何工作的,然后再学习如何以简单的方式做事。所以,一旦你明白了为什么会这样,就去阅读上面的文档吧



最后,假设您使用的是CPython或另一个基于GIL的实现,而
derivate\u solver
函数不是一个明确设计用于在没有GIL的情况下完成大部分工作的C扩展函数,那么这从一开始就不是一个好主意。当您需要没有并行性的并发性时(因为您的代码更简单,或者因为它是I/O绑定的),线程是很好的,但是当您实际上试图从多个内核中获益时,它们不是答案,因为一次只有一个线程可以运行解释器。如果需要并行性,请使用
多处理
(或仅使用
并发.futures.ProcessPoolExecutor
而不是
并发.futures.ThreadPoolExecutor

您编写的示例令人困惑。为什么
return
在函数之外?@minerals:这个例子是OP的导数函数内部的一段代码。所有这些,包括本地
enthread
定义。(因为
enthread
在这里不需要关闭任何局部变量,如果您想重用它,可以将它移到顶层,但是将它留在这里可以避免用一个您不打算重用的函数污染名称空间。)线程是没有回报的,它几乎是无用的,浪费了coffe循环。我花了太多的时间来决定使用队列,这是认真编码的必要条件。我尝试了一些快捷方式,但毕竟你应该使用queue或外部方法,这肯定会慢一些。
queue.queue
。一个简单的
[]
就可以了。