我最近开始学习如何用python编写多线程程序,对于初学者来说,我开始尝试不用使用队列。
在下面的代码中,loadFunction只是线程的示例目标函数。 假定,要等到wait(list)参数中提供的所有线程执行完毕(并且我正在尝试使用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
这是我编写此代码时想到的两件事(引自the official documentation):
join(timeout = None)
等待直到线程终止。这阻止了通话 直到调用join()方法的线程终止为止
在我的示例代码中,“调用线程”是调用loadFunction函数的哪个线程?我有一个 轻微 怀疑,事实并非如此,进程本身调用了函数而不是线程,因此该线程不是等待中的那个,而是进程等待。如果是这种情况,我该如何解决?我感觉会涉及到队列... 如果,这首先是原因。
和:
一个线程可以被多次join()。
是导致我两次对同一线程使用join的原因。
P.S。我是第一次在python中学习线程,但这是在学习C语言中的派生过程之后,因此,也许我 可能 在这里变得有些困惑。如果两者不相关,那么我很抱歉,我的印象是两者相似(尽管显然不相同,因为一个人拆分了流程,而另一个则在流程内部创建了线程)。
谢谢。
答案 0 :(得分:1)
无论调用loadFunction函数的那个线程是“调用线程”吗?
调用线程是称为join
的线程。因此t1.join()
和t2.join()
和t3.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))
答案 1 :(得分:0)
如果要在开始第三个线程之前等待两个第一个线程完成,请不要在start()
插入其他两个线程之前在第三个线程上调用join()
:
t1.start()
t2.start()
# wait for the threads above to finish before starting the third
t1.join()
t2.join()
t3.start() #now start it
t3.join() # wait for it to finish