目录
- 1. 语法
- 2. 示例代码
- 2.1 基本用法:等待线程执行完成
- 2.2 设置超时时间
timeout
- 2.3 多线程并行
join()
- 3.
join()
相关特性- 3.1
join()
只对start()
过的线程有效 - 3.2
join()
不能用于主线程等待自己 - 3.3
join()
不能强制结束线程
- 3.1
- 4.
join()
的实际应用场景 - 5. 总结
threading.Thread.join()
是 Python threading
模块中的一个方法,用于阻塞调用它的线程,直到目标线程执行完成(即 Thread
对象的 run()
方法执行结束)。该方法通常用于确保多线程程序按照预期的顺序执行,避免主线程过早退出或与子线程出现资源竞争问题。
1. 语法
thread.join(timeout=None)
timeout
(可选):指定最多等待目标线程终止的时间(单位:秒)。如果未提供timeout
,则主线程会无限期等待目标线程执行完成。join()
不会终止线程,只是等待它结束。
2. 示例代码
2.1 基本用法:等待线程执行完成
import threading
import timedef worker():print("线程开始执行...")time.sleep(2)print("线程执行完毕!")# 创建线程
t = threading.Thread(target=worker)
t.start()print("主线程等待子线程完成...")
t.join() # 阻塞主线程,直到 t 线程执行完毕
print("主线程继续执行!")
输出示例:
主线程等待子线程完成...
线程开始执行...
线程执行完毕!
主线程继续执行!
主线程会等待 t
线程执行完毕后,才会继续向下运行。
2.2 设置超时时间 timeout
import threading
import timedef worker():print("线程开始执行...")time.sleep(5)print("线程执行完毕!")t = threading.Thread(target=worker)
t.start()print("主线程等待 2 秒...")
t.join(timeout=2) # 最多等待 2 秒
print("主线程继续执行!(不管子线程是否完成)")
可能的输出:
主线程等待 2 秒...
线程开始执行...
主线程继续执行!(不管子线程是否完成)
线程执行完毕!
主线程最多等待 2 秒,之后会继续执行,即使 t
线程尚未完成。
2.3 多线程并行 join()
在多个线程中使用 join()
以确保所有线程都执行完毕:
import threading
import timedef worker(n):print(f"线程 {n} 开始")time.sleep(n)print(f"线程 {n} 结束")threads = []for i in range(3):t = threading.Thread(target=worker, args=(i+1,))t.start()threads.append(t)# 等待所有线程执行完成
for t in threads:t.join()print("所有线程执行完毕,主线程继续!")
可能的输出:
线程 1 开始
线程 2 开始
线程 3 开始
线程 1 结束
线程 2 结束
线程 3 结束
所有线程执行完毕,主线程继续!
join()
确保所有子线程都执行完毕后,主线程才会继续执行。
3. join()
相关特性
3.1 join()
只对 start()
过的线程有效
如果 join()
在一个尚未启动的线程上调用,它不会生效:
import threadingt = threading.Thread(target=lambda: print("线程运行"))
t.join() # 这里不会阻塞,因为线程 t 还没 start()
print("主线程继续执行")
输出:
主线程继续执行
解释: t.join()
立即返回,因为 t
线程根本没有 start()
过。
3.2 join()
不能用于主线程等待自己
如果 join()
在主线程中对自身调用,会导致死锁:
import threading
import timedef worker():print("子线程执行中...")time.sleep(2)print("子线程执行完毕")t = threading.Thread(target=worker)
t.start()threading.current_thread().join() # 试图让主线程等待自己
错误:
RuntimeError: cannot join current thread
解释: join()
会让调用它的线程阻塞等待目标线程结束,但如果主线程调用 join()
来等待自己,主线程就会永远卡住,导致死锁。
3.3 join()
不能强制结束线程
import threading
import timedef worker():while True:print("线程运行中...")time.sleep(1)t = threading.Thread(target=worker)
t.start()time.sleep(3)
t.join(timeout=1) # 主线程等待 1 秒
print("主线程继续执行")
输出(不会停止 t
线程):
线程运行中...
线程运行中...
线程运行中...
主线程继续执行
线程运行中...
...
解释: join()
只是等待线程结束,而不是强制终止线程。要停止线程,通常需要在 worker()
里用标志位来手动退出循环。
4. join()
的实际应用场景
- 确保主线程等待子线程完成(避免主线程退出导致子线程被强制终止)。
- 控制线程执行顺序,比如一个线程的任务依赖于另一个线程的结果。
- 使用
timeout
限制等待时间,防止子线程运行时间过长导致主线程被无限阻塞。
5. 总结
join()
用于等待线程完成,阻塞主线程或调用它的线程。join(timeout)
允许设定超时时间,不会强制终止线程。- 不能在未
start()
的线程上调用join()
。 - 不能对当前线程调用
join()
,否则会死锁。 - 不能强制终止线程,仅用于等待。
你可以在你的多线程应用中使用 join()
来保证线程按照预期的顺序执行,提高程序的稳定性和可靠性! 🚀