1. 线程的概念
线程是计算机执行的最小单位,是进程中的一个实体,是进程中的一个执行流,是CPU的基本调度单位。线程自己不拥有系统资源,只拥有在运行中必不可少的一些资源(如程序计数器、一组寄存器和栈),但是它可与同属一个进程的其他线程共享进程所拥有的全部资源。
Python提供了多线程编程的支持,可以通过threading模块创建线程。
2. join方法的概念
join方法是线程类(threading.Thread)的一个方法,用于阻塞主线程,等待子线程执行完毕。
class threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)
def join(self, timeout=None):
"""
Wait until the thread terminates.
This blocks the calling thread until the thread whose join() method is called terminates.
"""
if timeout is None:
self._wait_for_tstate_lock()
else:
# ...
在调用join方法时,主线程会等待被调用的子线程执行完毕,才会继续往下执行。如果子线程不调用join方法,主线程就会继续执行,不会等待子线程。
3. join方法的原理
在Python的threading模块中,join方法实际上就是通过调用_thread模块中的start_new_thread函数来创建线程,然后在子线程中调用threading模块中的_current_thread函数来等待子线程执行完毕。
3.1 创建线程
在调用join方法时,首先会获取当前线程,然后创建新的线程。可以通过子线程的start方法来启动线程:
import threading
def worker():
print("Worker")
thread = threading.Thread(target=worker)
thread.start()
上述代码中,创建了一个名为thread的新线程,并指定target为worker函数。worker函数是子线程执行的任务,这里只简单地打印了"Worker"。
3.2 等待线程
在子线程中调用join方法时,会通过调用threading模块中的_current_thread函数来等待线程的结束:
import threading
def worker():
print("Worker")
thread = threading.Thread(target=worker)
thread.start()
thread.join()
print("Main Thread")
上述代码中,子线程通过join方法来等待线程的结束,然后主线程才会继续执行打印"Main Thread"。如果去掉join方法,会发现主线程会先于子线程结束。
3.3 join方法的超时参数
join方法还可以传入一个超时参数(单位为秒),表示等待线程的最大时间。如果线程在超时时间内没有执行完毕,则join方法会返回。超时参数为可选参数,默认为None。
例如:
import threading
def worker():
import time
time.sleep(2)
print("Worker")
thread = threading.Thread(target=worker)
thread.start()
thread.join(timeout=1)
print("Main Thread")
在上述代码中,子线程会等待2秒钟后才会打印"Worker",而主线程在等待了1秒钟后就继续打印"Main Thread",不会等待整个2秒钟。
4. join方法的应用场景
join方法主要用于等待子线程的结束,常见的应用场景有:
主线程需要等待子线程完成某个任务后再继续执行后续代码。
多个子线程之间需要协同工作,其中一个子线程的执行依赖于其他子线程。
例如:
import threading
def worker(task):
print("Worker", task)
thread1 = threading.Thread(target=worker, args=("A",))
thread2 = threading.Thread(target=worker, args=("B",))
thread3 = threading.Thread(target=worker, args=("C",))
thread1.start()
thread2.start()
thread3.start()
thread1.join()
thread2.join()
thread3.join()
print("Main Thread")
上述代码中,创建了三个子线程,并分别传入不同的任务(A、B、C)。主线程需要等待所有子线程都执行完毕后才会打印"Main Thread"。
5. 总结
join方法是线程的一个重要方法,可以用于阻塞主线程等待子线程的结束。它的原理是通过创建线程和等待线程的方式来实现。join方法在多线程编程中非常有用,可以用于任务的协同工作和主线程的等待。