Python Threads

A Python thread is like a process, and may even be a process, depending on the Python thread system. In fact, Python threads are sometimes called "lightweight" processes, because threads occupy much less memory, and take less time to create, than do processes. Threads allow applications to perform multiple tasks at once. Multi-threading is important in many applications.
Two modules, and serve as Python Threads. We start our discussion from
Python Thread by Thread module
Python Threads by thread module
Click to view code
You can see we have created two threads, By figure you can understand how thread take arguments. Python Thread module is easy to implement however thread module is very limited compared to the newer threading module. So good practice is to use threading module.

Python Threading modules

Define a new subclass of the Python Thread class. New class inherit the Python threading class. Override the constructor __init__(self [,args]) method to add additional arguments. Then, override the run(self [,args]) method to implement what the thread should do when started
Learn by example
Python Threads by threading module
Threads by threading module
Click to view code
The above program gives the idea of minimum condition to run the Python threading program.
run(): The run() method is the entry point for a python thread. This is the section where you can put your logic part
start(): The start() method starts a Python thread by calling the run method
thread1 = mythread(1) creating thread
The threading.Thread.__init__(self) here subclass mythread overrides the constructor so base class constructor constructor (Thread.__init__()) must be invoked.

Let us discuss some more interesting program in python
threading.activeCount(): Returns the number of total Python thread that are active.
threading.currentThread(): Returns the number of Python thread objects in the caller's thread control.
threading.enumerate(): Returns a list of all Python thread objects that are currently active.

Let us discuss our next example.
Total thread count by Python threading.activeCount()
Click to view code

threading.activeCount() return 11 threads, 10 threads created by for loop and one is main thread.

join(self, timeout=None) or sometime Join() function
In very simple words Join() function is used to terminate the threads.
Learn form example With-out join()
Python thread with-out join()
with-out join()
Click to view code

So you can see where is "good by". so my aim string "good by" should be print end of the program. Now use I use join()
Python thread termination  with join()
with join()
Click to view code
I think you understood what I want to show. Before print "good by" both threads are terminated.

Let us discuss another problem of join().
Python thread termination  with for join()
with join() for loop
Click to view code
In above program you can see that threads are being created by for loop and join() is used within the for loop.

Consider you want to start all thread at once and work one by one ,So I use lock mechanism Program 7
Python Thread with lock system
Threads with lock
Click to view code
Locks are the most fundamental synchronization mechanism provided by threading module. A lock is in one of two states, locked or unlocked. If a thread attempts to hold a lock that's already held by some other thread, execution of the first thread is halted until the lock is released.

lock.acquire (blocking):
Acquire a lock, blocking or non-blocking. When invoked with the blocking argument set to True (the default), block until the lock is unlocked, then set it to locked and return True When invoked with the blocking argument set to False, do not block.

Returns True if lock is locked, otherwise False.

Unlocks lock, which must be locked. When lock is locked, any thread may call lock

RLock is a reentrant lock.acquire() can be called multiple times by the same thread without blocking. Keep in mind that release() needs to be called the same number of times to unlock the resource. Defined like this rlock = threading.RLock()

Let us discuss next example of threads with list.
Python Threads with lock and join
Threads with lock and join
Click to view code
In above program threads are added in the given list. In next for loop thread.join() terminate the threads.

Python Daemon thread

Python docs says A thread can be flagged as a "daemon thread". The significance of this flag is that the entire Python program exits when only daemon threads are left. This must be set before start() is called, otherwise RuntimeError is raised. Its initial value is inherited from the creating thread; the main thread is not a daemon thread and therefore all threads created in the main thread default to daemon = False.
The entire Python program exits when no alive non-daemon threads are left.
What is main thread ? Let us learn by program
Main Thread
Click to view code
I have not declared any thread, why is the thread running ? Answer is, a thread is like a process that one thing currently happening here and your python program code is currently running with a thread. Program you running a thread itself that is called main thread.

So I create another thread program.
Python main thread
Click to view code
Threading.enumerate() return a list of active threads.

Check main thread is daemon or not.
Threading.enumerate() give active Python threads
Threading.enumerate() give active threads
Click to view code
The threading.enumerate() return the list of active threads and threading.enumerate()[0] return first thread of list. So main_th.isDaemon return False means main thread is not daemon thread. Thread created with in main thread is not daemon by default.

How to set particular threads is daemon.
Thread_name.setDaemon(True) use this syntax. As shown in next program.
Python daemon thread
Set daemon thread
Click to view code
You can see thread2 is set as daemon thread.

If you want to only function and no class. Just define the function and create thread like this

from threading import Thread
t = Thread(target=function_name, args=(i,))
= give the function name.
args = argument pass to target function.
Python Thread from threading
Thread function
Click to view code
Now you can see in the program threads t executes the function sleeper() and threads t1 executes the function fun().

If you want to check the thread is alive or not at any moment , use isAlive()
Let us discuss in the program.
Checking Python thread live or not by isAlive()
Checking Thread live or not
Click to view code
Output of the program is showing that t1 thread was not live and t2 was live before end of the program. Because time.sleep(2) means thread is sleeping for 2 seconds and t1.join(3) terminates the thread after 3 seconds so after 3 second thread t1 will die. For thread t2 terminate time is 1 second as mentioned in t2.join(1) but during that time thread t2 was sleeping so thread was still alive.
Now back to Daemon thread definition
See the example below.
use of Python daemon thread
Daemon Thread
Click to view code
You can see the above program. Two function n() and d() are created. The daemon thread calls the function d() and the non-daemon thread calls function n(). The daemon thread waits for the five seconds by using statement time.sleep(5), but main thread does not wait for the daemon thread to exit. So statement "daemon stop" is not printed.

Now check the another example.
Python daemon thread explain
Daemon Thread
Click to view code
This time the non-daemon thread is waiting for 5 seconds, but main program waits for the non-daemon thread to exit.
Let us discuss our next example.
Difference between  Python daemon  and non-daemon thread explain
Daemon Thread
Click to view code
In above program main program waits for 5 second to exit. In our above program, join() blocks the calling thread (main thread) until the threads (d and t) whose join() method is called is terminated.