In my previous post, I explained in detail what are all the possible ways of using threading, from synchronous to asynchronous processes, exploiting both single threading and multi-threading.
In python, the reference library to run threads is called threading. Threads are different from regular functions, therefore we cannot call them in the same way we call functions, but we need to use a specific class for them.
Threading becomes more interesting when you run multiple tasks simultaneously, but there are almost no examples of how running a single thread behaves, and what this implies when running some code.
How is running a single thread useful?
Before running any code, know that you need to have installed the threading library, you can easily do this with pip:
!pip install threading
A thread runs separately from the rest of the code. It is much simpler to understand the behavior of a thread when a single one is running, instead of presenting you with a bunch of complex code. In the following example, I will try to run simultaneously one thread and the rest of the code, so we can see the output of the entire code:
#single-thread def thread_1_foo(val): for a in range(val): print(val) print('thread_1 finished') #creating thread thread_1 = threading.Thread(target=thread_1_foo, args=(100,)) thread_1.start() print("Done!")
As you can see, the thread function thread_1_foo() takes an input (in our case 100) and just prints the value from 0 to that value with a for cycle. If this was a regular code, we would expect the for cycle to reach 100, and only then the print function to print “Done!” on the console:
#how the output would look on a regular code 0 1 2 ... 100 Done!
However, this is what happens when we use threads:
#how the output would look with threads 0 Done! 1 2 ... 100
As we can see, your code, which only consists of a Done! function, runs at the same time with your thread.
Of course, when you are using threads you do not want them to take priority over your code all the time. If they had to pass variables to the rest of your code, to avoid this problem you would only need to use threads. This is, unfortunately, quite uncomfortable. To solve the problem, I will use a threading method called join().
What this does is prevent all the code after the join from running before the thread has finished its job. Let us see an example:
#single-thread def thread_1_foo(val): for a in range(val): print(val) print('thread_1 finished') #creating thread thread_1 = threading.Thread(target=thread_1_foo, args=(100,)) thread_1.start() #join waits for the thread to die #any code after join has to wait for the join process to end thread_1.join() print("Done!")
Now that we have written the code, let us have a look at the output:
0 1 2 ... 100 Done!
Even when using a thread, your code (at least the print() function) waits for the thread to finish before executing, which is exactly what we wanted.
Do you wish to read similar articles to increase your Python level? Follow me on Medium!