In this second part of the Thread in Python series, we will see how it is possible to influence the execution of multiple threads thanks to the use of Join.
Let’s modify the previous example to have more control over each individual thread. We create two threads that will wait for two different times, for example 10 and 4 seconds. In this way I will always know that the first thread will last longer than the second.
Furthermore both threads will last longer than the execution of the program. The two seconds added at the end of the program I need to make sure that the program ends after the creation of the second thread.
from threading import Thread import time def thread1(): print("Thread 1 started") time.sleep(10) print("Thread 1 ended") def thread2(): print("Thread 2 started") time.sleep(4) print("Thread 2 ended") print("Main start") t1 = Thread(target=thread1) t2 = Thread(target=thread2) t1.start() t2.start() time.sleep(2) print("Main end")
Executing the code …
It is very clear that the program starts the two threads and then ends after two seconds. Instead the two threads will continue to work. First the second thread will end and then the first one. Everything behaves as we wanted. By performing several times, we will always have the same result.
But what if we wanted a different sequence? For example we want the program to wait for the end of the second thread before it stops.
The thread.join() function exists in the threading module. This launched in the thread will force the program to wait for the execution of the thread to complete before it can be closed.
We then add the join to the second thread to the code first.
... t2.start() t2.join() time.sleep(2) ...
And execute it.
It is clear that the program will now wait for the end of the second thread before finishing.
If instead we use the join () for the first thread.
t2.start() t1.join() time.sleep(2)
And executing ..
We see that the program will now wait for the end of the first thread, which being the one that takes the most time, we will have all the threads terminated before the closure of the program.
Now, except for this particular case, in which we know very well the duration of each thread (we have forced things …), it is almost impossible to predict the times and durations of each thread. If we want the program to wait for all threads to complete, it’s a good idea to add joins to all the individual threads.
In this second part we have seen the role of the Join within the threads and how these can influence the execution of multiple threads together. In the next part, we will further explore the topic of threads, introducing the Multithreading itself.