Blocking and non-blocking threads in python - Simplified
What is a non blocking thread?
In computer science, an algorithm is called non-blocking if failure or suspension of any thread cannot cause failure or suspension of another thread; for some operations, these algorithms provide a useful alternative to traditional blocking implementations.
So in layman's term,
A thread is non-blocking when it doesn't cause other threads to wait until the other thread(s) are finished.
What is a blocking thread?
In contrast a blocking thread is the thread that will wait before some other thread or threads have finished their execution.
Real life examples exist for both the types of thread processes in computing.
In this tutorial we will simulate both these type of threads.
Major use of threading is to have a thread that is infact non-blocking so that we could do more with lesser time if both of the threads don't necessarily "connect" or are dependent on each other.
Code for non-blocking thread (with comments) :
# importing libraries
import random
import time
from threading import Thread
# target function which takes a time at random(from 0 to 2 seconds) to simulate some "work"
def worker(instance):
time_taken = random.uniform(0, 2)
time.sleep(time_taken)
print('thread %s : completed in %s sec' % (instance, time_taken))
if __name__ == '__main__':
for i in range(0, 10):
# don't confuse with the variable "t" it is not bound to any thread! it is just a name
t = Thread(target=worker, args=(i,))
# starting the thread which will continue working in background after this.
t.start()
Output:
Explanation:
Hope you have read the comments.
So what the code does is that it starts 10 threads named thread 0,thread 1 and so on on a worker() which simulates some work using time.sleep() with random time.
when a thread completes we can see that it outputs the time in which it got completed.
We can see from the output that the threads may have started sequentially but they don't get completed sequentially like thread 5 got completed before thread 0.
If we make a small modification and add some code to the main program outside of thread then we can see how it works and no thread is dependent on neither the other threads or the main program.
Code:
# importing libraries
import random
import time
from threading import Thread
# target function which takes a time at random(from 0 to 2 seconds) to simulate some "work"
def worker(instance):
time_taken = random.uniform(0, 2)
time.sleep(time_taken)
print('thread %s : completed in %s sec' % (instance, time_taken))
if __name__ == '__main__':
for i in range(0, 10):
# don't confuse with the variable "t" it is not bound to any thread! it is just a name
t = Thread(target=worker, args=(i,))
# starting the thread which will continue working in background after this.
t.start()
# this just simulates a main program that does some work which takes 2 seconds of time
time.sleep(1)
print("Hi,there.Main program here!")
Output :
Explanation :
Similar to the other program the only difference is a main program included that works independent of the threads.
A blocking thread in contrast to the above examples will wait for other threads to finish their execution.
Although we wouldn't require using such threads as usually the purpose of a thread is parallelism and concurrency which blocking threads don't do.
code:
# importing libraries
import random
import time
from threading import Thread
# target function which takes a time at random(from 0 to 2 seconds) to simulate some "work"
def worker(instance):
time_taken = random.uniform(0, 2)
time.sleep(time_taken)
print('thread %s : completed in %s sec' % (instance, time_taken))
if __name__ == '__main__':
# this just simulates a main program that does some work which takes 2 seconds of time
for i in range(0, 10):
# don't confuse with the variable "t" it is not bound to any thread! it is just a name
t = Thread(target=worker, args=(i,))
# starting the thread which will continue working in background after this.
t.start()
t.join() #the only change in the code to make it a blocking thread!!!
Output:
Explanation:
The only modification in the code we did is t.join() what this does is that it will wait or the previous thread to complete its execution before starting up and same way other threads would work.
Comments