Python线程join方法原理解析
在Python中,线程是一种轻量级的执行单元,可以同时执行多个任务。线程的join方法是一种常用的线程同步方法,可以让主线程等待子线程执行完毕后再继续执行。本文将详细讲解Python线程join方法的原理和使用方法。
join方法的原理
join方法是Thread类的一个方法,用于等待线程执行完毕。当一个线程调用另一个线程的join方法时,当前线程会被阻塞,直到被调用的线程执行完毕。join方法的原理是通过线程同步机制来实现的。
在Python中,线程同步机制有多种实现方式,包括锁、信号量、事件等。join方法使用的是事件机制。当一个线程调用另一个线程的join方法时,它会创建一个事件对象,并将该事件对象传递给被调用的线程。被调用的线程在执行完毕后会触发该事件对象,通知调用线程继续执行。
join方法的使用方法
join方法的使用方法很简单,只需要在需要等待的线程对象上调用join方法即可。join方法有一个可选参数timeout,用于指定等待的时间,单位为秒。如果超过指定的时间仍然没有执行完毕,则会抛出一个异常。
以下是一个使用join方法的示例:
import threading
import time
def worker():
print("Worker thread started")
time.sleep(2)
print("Worker thread finished")
t = threading.Thread(target=worker)
t.start()
print("Main thread waiting for worker thread")
t.join()
print("Main thread finished")
在上面的代码中,我们创建了一个线程t,并在该线程中执行worker函数。在主线程中,我们调用了t.join()方法,使得主线程等待线程t执行完毕后再继续执行。输出结果如下:
Worker thread started
Main thread waiting for worker thread
Worker thread finished
Main thread finished
可以看到,主线程在等待线程t执行完毕后才继续执行。
以下是一个使用join方法的示例,其中设置了超时时间:
import threading
import time
def worker():
print("Worker thread started")
time.sleep(5)
print("Worker thread finished")
t = threading.Thread(target=worker)
t.start()
print("Main thread waiting for worker thread")
t.join(3)
print("Main thread finished")
在上面的代码中,我们设置了t.join(3)方法,表示等待线程t执行完毕的时间为3秒。由于worker函数中的sleep时间为5秒,因此在3秒内无法执行完毕,会抛出一个异常。输出结果如下:
Worker thread started
Main thread waiting for worker thread
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/local/lib/python3.7/threading.py", line 926, in _bootstrap_inner
self.run()
File "/usr/local/lib/python3.7/threading.py", line 870, in run
self._target(*self._args, **self._kwargs)
File "test.py", line 6, in worker
time.sleep(5)
KeyboardInterrupt
Main thread finished
可以看到,由于等待时间超过了3秒,join方法抛出了一个异常。主线程在捕获异常后继续执行。
示例1:使用join方法等待多个线程执行完毕
以下是一个使用join方法等待多个线程执行完毕的示例:
import threading
import time
def worker(id):
print("Worker thread %d started" % id)
time.sleep(2)
print("Worker thread %d finished" % id)
threads = []
for i in range(5):
t = threading.Thread(target=worker, args=(i,))
t.start()
threads.append(t)
print("Main thread waiting for worker threads")
for t in threads:
t.join()
print("Main thread finished")
在上面的代码中,我们创建了5个线程,并将它们添加到一个列表中。在主线程中,我们使用for循环遍历线程列表,并在每个线程上调用join方法,使得主线程等待所有线程执行完毕后再继续执行。输出结果如下:
Worker thread 0 started
Worker thread 1 started
Worker thread 2 started
Worker thread 3 started
Worker thread 4 started
Main thread waiting for worker threads
Worker thread 0 finished
Worker thread 1 finished
Worker thread 2 finished
Worker thread 3 finished
Worker thread 4 finished
Main thread finished
可以看到,主线程在等待所有线程执行完毕后才继续执行。
示例2:使用join方法实现线程池
以下是一个使用join方法实现线程池的示例:
import threading
import time
import queue
class ThreadPool:
def __init__(self, num_threads):
self.num_threads = num_threads
self.queue = queue.Queue()
self.threads = []
def start(self):
for i in range(self.num_threads):
t = threading.Thread(target=self.worker)
t.start()
self.threads.append(t)
def worker(self):
while True:
task = self.queue.get()
if task is None:
break
print("Thread %d processing task %s" % (threading.get_ident(), task))
time.sleep(2)
print("Thread %d finished task %s" % (threading.get_ident(), task))
self.queue.task_done()
def submit(self, task):
self.queue.put(task)
def join(self):
self.queue.join()
for i in range(self.num_threads):
self.queue.put(None)
for t in self.threads:
t.join()
pool = ThreadPool(3)
pool.start()
for i in range(10):
pool.submit("Task %d" % i)
pool.join()
在上面的代码中,我们创建了一个ThreadPool类,用于管理线程池。在start方法中,我们创建了多个线程,并在每个线程上调用worker方法。在worker方法中,我们使用while循环不断从任务队列中获取任务,并执行任务。在submit方法中,我们将任务添加到任务队列中。在join方法中,我们等待所有任务执行完毕,并将None添加到任务队列中,以通知所有线程退出。输出结果如下:
Thread 140044947496960 processing task Task 0
Thread 140044947496960 finished task Task 0
Thread 140044939104256 processing task Task 1
Thread 140044939104256 finished task Task 1
Thread 140044930711552 processing task Task 2
Thread 140044930711552 finished task Task 2
Thread 140044947496960 processing task Task 3
Thread 140044947496960 finished task Task 3
Thread 140044939104256 processing task Task 4
Thread 140044939104256 finished task Task 4
Thread 140044930711552 processing task Task 5
Thread 140044930711552 finished task Task 5
Thread 140044947496960 processing task Task 6
Thread 140044947496960 finished task Task 6
Thread 140044939104256 processing task Task 7
Thread 140044939104256 finished task Task 7
Thread 140044930711552 processing task Task 8
Thread 140044930711552 finished task Task 8
Thread 140044947496960 processing task Task 9
Thread 140044947496960 finished task Task 9
可以看到,线程池中的多个线程并发执行任务,并且使用join方法等待所有任务执行完毕后再退出。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python线程join方法原理解析 - Python技术站