首页 > 解决方案 > Thread.join() 在 python 中到底做了什么?这是对 Thread.join() 的错误使用吗?

问题描述

我最近开始学习如何在 python 中编写多线程程序,对于初学者来说,开始在使用队列的情况下进行实验。

在下面的代码中,loadFunction 只是线程的一个示例目标函数。它应该等到等待(列表)参数中提供的所有线程都完成执行(我正在尝试使用 join() 来实现这一点)。然后开始打印指定的数字范围这是期望的行为。

在主程序中,我创建了两个线程,它们不等待任何其他线程开始计数。然后我创建了第三个线程,它应该在开始计数之前等待前两个线程完成执行。

然而,这并没有发生。在测试中,我发现三个线程同时开始执行,而第三个线程并没有像我预期的那样等待前两个线程完成执行。

所以我的问题是,我缺少关于 Thread.join() 函数的哪些知识,以及我可以对我的代码进行哪些更改以达到预期的结果?

代码:

""" Note: Python 3.3 onwards required since daemon was added as an initializable
    property from python 3.3 onwards."""

import threading

def loadFunction(name, start, end, wait=[]):
    """ wait should be a list of threads to wait for """
    map(lambda th: th.join(), wait)
    for number in range(start, end):
        print("%s : %d" % (name, number))

if __name__ == "__main__":
    t1 = threading.Thread(target=loadFunction, args=("Thread1", 1, 101), name="Thread1" ,daemon=True)
    t2 = threading.Thread(target=loadFunction, args=("Thread2", 101, 201), name="Thread2", daemon=True)
    t3 = threading.Thread(target=loadFunction, args=("Thread3", 1000, 1101, [t1, t2]), name="Thread3", daemon=True)

    t1.start()
    t2.start()
    t3.start()

    # wait for all of the daemon processes to finish before we close the program
    t1.join()
    t2.join()
    t3.join()

    print("done!")

结果的一部分(一次运行):

Thread1 : 1
Thread1 : 2
Thread1 : 3
Thread1 : 4
Thread1 : 5
Thread1 : 6
Thread2 : 101
Thread2 : 102
Thread2 : 103
Thread2 : 104
Thread2 : 105
Thread2 : 106
Thread2 : 107
Thread2 : 108
Thread2 : 109
Thread1 : 7
Thread1 : 8
Thread1 : 9
Thread1 : 10
Thread1 : 11
Thread3 : 1000
Thread1 : 12
Thread1 : 13
Thread3 : 1001
Thread1 : 14
Thread3 : 1002
Thread1 : 15
Thread3 : 1003
Thread1 : 16
Thread2 : 110

这是我在编写这段代码时想到的两件事(引用自官方文档):

加入(超时=无)

等到线程终止。这会阻塞调用线程,直到调用其 join() 方法的线程终止...

参考我的示例代码,“调用线程”会是调用 loadFunction 函数的线程吗?我有点怀疑情况并非如此,并且进程本身调用了函数而不是线程,因此线程不会是等待的线程,而是进程等待。如果是这种情况,我将如何解决它?我有一种感觉会涉及到排队……如果这首先是原因的话。

和:

一个线程可以被 join() 多次。

是什么导致我两次将 join 用于同一线程。

PS 我第一次在 python 中学习线程,但这是在学习 C 中的分叉过程之后,所以我可能会因此而在这里感到困惑。如果两者不相关,那么我很抱歉,我的印象是两者是相似的(尽管显然不一样,因为一个拆分进程,而另一个在进程本身内创建线程)。

谢谢你。

标签: pythonmultithreadingpython-multithreading

解决方案


“调用线程”会是调用 loadFunction 函数的线程吗?

调用线程是调用的线程join。so t1.join()and t2.join()andt3.join()导致主线程阻塞,如果没有延迟评估,内部的连接loadFunction会导致 t3 阻塞。map

我将如何解决它?

您内部loadFunction的连接没有执行,因为map在您迭代它之前不会执行任何代码。正如 MaxNoe 建议的那样,您应该改用普通的 for 循环。

def loadFunction(name, start, end, wait=[]):
    """ wait should be a list of threads to wait for """
    for t in wait:
        t.join()
    for number in range(start, end):
        print("%s : %d" % (name, number))

推荐阅读