When working with multiple threads we need to ensure that the main program waits until all spawned threads have completed their tasks. In this article, we will see how to ensure all threads are finished before the main program terminates.
Using join()
Method
Using the join() method, we can wait for a thread to complete. This method blocks the calling thread (Here main method) until the thread whose join()
method called is terminated.
Following is the example:
import threading
import time
def worker():
print("Thread is starting")
time.sleep(2) # Simulate a task taking some time
print("Thread is finishing")
# Create threads
threads = []
for i in range(5):
thread = threading.Thread(target=worker)
thread.start()
threads.append(thread)
# Wait for all threads to complete
for thread in threads:
thread.join()
print("All threads have finished.")
In the above example, five worker threads are created. The main thread waits for each of the spawned threads to complete by calling join()
on each thread.
Using a ThreadPoolExecutor
Using the python’s concurrent.futures
module we can manage a pool of threads. This module provides the ThreadPoolExecutor
, which simplifies thread management and provides an easy way to wait for all threads to complete.
Following is the example of ThreadPoolExecutor
import concurrent.futures
def worker():
print("Thread is starting")
time.sleep(2)
print("Thread is finishing")
return "Done"
# Create a ThreadPoolExecutor
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
futures = [executor.submit(worker) for _ in range(5)]
for future in concurrent.futures.as_completed(futures):
print(future.result())
print("All threads have finished.")
In the above example, the ThreadPoolExecutor
manages a pool of five worker threads. The submit()
method schedules the worker
function to be executed and returns a future object. The as_completed()
yields futures when the spawned threads finish the execution.