In Python, joining the threads means using the join() method to wait for one thread to finish before moving on to others. This is useful in multithreaded programming to make sure some threads are completed before starting or continuing with other threads. By using the join() method, you can make sure that one thread has finished running before another thread or the main program continues. In this tutorial you will get the detailed explain of the join() method with suitable examples.
Joining the Threads in Python
To join the threads in Python, you can use the Thread.join() method from the threading module. Which generally is used to block the calling thread until the thread on which join() was called terminates. The termination may be either normal, because of an unhandled exception − or until the optional timeout occurs. You can call join() multiple times. However, if you try to join the current thread or attempts to join a thread before starting it with the method, will raise the RuntimeError exception.
Following is the syntax of the Thread.join() method −
thread.join(timeout)
Where, the timeout is an optional parameter that takes a floating-point number specifying the maximum wait time in seconds (or fractions thereof). If it is not provided or None, the method will block until the thread terminates.
This method always returns None. After calling join(), you can use is_alive() to check if the thread is still running. This is useful to determine if the join() call timed out.
Example
The following example demonstrates the use of join() in a multithreaded program. It starts two threads (thread1 and thread2). Initially, it blocks the main thread until thread1 finishes executing the my_function_1. After thread1 completes, thread2.start() is called, followed by thread2.join() to ensure that the main thread waits until thread2 finishes executing my_function_2().
from threading import Thread from time import sleep def my_function_1(arg): for i in range(arg): print("Child Thread 1 running", i) sleep(0.5) def my_function_2(arg): for i in range(arg): print("Child Thread 2 running", i) sleep(0.1) # Create thread objects thread1 = Thread(target=my_function_1, args=(5,)) thread2 = Thread(target=my_function_2, args=(3,)) # Start the first thread and wait for it to complete thread1.start() thread1.join() # Start the second thread and wait for it to complete thread2.start() thread2.join() print("Main thread finished...exiting")
When the above code is executed, it produces the following result −
Child Thread 1 running 0 Child Thread 1 running 1 Child Thread 1 running 2 Child Thread 1 running 3 Child Thread 1 running 4 Child Thread 2 running 0 Child Thread 2 running 1 Child Thread 2 running 2 Main thread finished...exiting
Example
Here is another example that demonstrates how the join() method with a timeout allows waiting for a thread to complete for a specified period, then proceeding even if the thread hasn”t finished.
from threading import Thread from time import sleep def my_function_1(arg): for i in range(arg): print("Child Thread 1 running", i) sleep(0.5) def my_function_2(arg): for i in range(arg): print("Child Thread 2 running", i) sleep(0.1) # Create thread objects thread1 = Thread(target=my_function_1, args=(5,)) thread2 = Thread(target=my_function_2, args=(3,)) # Start the first thread and wait for 0.2 seconds thread1.start() thread1.join(timeout=0.2) # Start the second thread and wait for it to complete thread2.start() thread2.join() print("Main thread finished...exiting")
When you run the above code, you can see the following output −
Child Thread 1 running 0 Child Thread 2 running 0 Child Thread 2 running 1 Child Thread 2 running 2 Child Thread 1 running 1 Main thread finished...exiting Child Thread 1 running 2 Child Thread 1 running 3 Child Thread 1 running 4