Sometimes it would be useful to have two python programs running at the same time this is easy just start two separate programs. But what if the programs need to share information, then its a bit more tricky. Threading is a way to run two processes independently and they can share data.
Threading code
In the program definition you need to to import the treading module. I have also imported time to create delays. To use a variable in other functions or classes it must be defined as global, it is then initialised with value 0.0.
from threading import Thread
import time
global cycle
cycle = 0.0
To use treading a new class is created Hello5Program this will be run in a new program thread. The class has three definitions. The __init__ definition initialises the class setting running parameter to true. The terminate definition is used to exit the class. The run definition is where the main class code is written. The global variable cycle is defined here again linking it to the main programs global variable.
class Hello5Program:
def __init__(self):
self._running = True
def terminate(self):
self._running = False
def run(self):
global cycle
while self._running:
time.sleep(5) #Five second delay
cycle = cycle + 1.0
print "5 Second Thread cycle+1.0 - ", cycle
An instance of the class Hello5Program is created as FiveSecond then a thread FiveSecondThread is created containing this classes run definition. The thread is started.
#Create Class
FiveSecond = Hello5Program()
#Create Thread
FiveSecondThread = Thread(target=FiveSecond.run)
#Start Thread
FiveSecondThread.start()
The rest of the main program has a loop increasing cycle by 0.1 and printing the result. When cycle is greater than 5 the program exits. As the program exits it must terminate the class by calling the terminate procedure. If the terminate procedure is not called the program will never exit.
Exit = False #Exit flag
while Exit==False:
cycle = cycle + 0.1
print "Main Program increases cycle+0.1 - ", cycle
time.sleep(1) #One second delay
if (cycle > 5): Exit = True #Exit Program
FiveSecond.terminate()
print "Goodbye :)"
Program result
The program output shows the increase of cycle by 0.1 then by 1.0 when the threaded runs both writing to the variable and printing the values. The thread finishes after the main program finishes because of the 5 second delay.
Many threads can be created to do different functions. A thread can call any function in the main program. I have used threads to read sensors and digital inputs with the main program displaying the outputs to an LCD display. All this using Raspberry PI GPIO pins and Python threads.
It is also possible to run the same class as many threads if that is required.
Code example with two different threads
Here is the whole code with an extra thread
from threading import Thread
import time
global cycle
cycle = 0.0
class Hello5Program:
def __init__(self):
self._running = True
def terminate(self):
self._running = False
def run(self):
global cycle
while self._running:
time.sleep(5) #Five second delay
cycle = cycle + 1.0
print "5 Second Thread cycle+1.0 - ", cycle
class Hello2Program:
def __init__(self):
self._running = True
def terminate(self):
self._running = False
def run(self):
global cycle
while self._running:
time.sleep(2) #Five second delay
cycle = cycle + 0.5
print "5 Second Thread cycle+1.0 - ", cycle
#Create Class
FiveSecond = Hello5Program()
#Create Thread
FiveSecondThread = Thread(target=FiveSecond.run)
#Start Thread
FiveSecondThread.start()
#Create Class
TwoSecond = Hello2Program()
#Create Thread
TwoSecondThread = Thread(target=TwoSecond.run)
#Start Thread
TwoSecondThread.start()
Exit = False #Exit flag
while Exit==False:
cycle = cycle + 0.1
print "Main Program increases cycle+0.1 - ", cycle
time.sleep(1) #One second delay
if (cycle > 5): Exit = True #Exit Program
TwoSecond.terminate()
FiveSecond.terminate()
print "Goodbye :)"
Thank You so much for explaining it so well. Can you please share the code for the understated:
ReplyDelete"threads to read sensors and digital inputs with the main program displaying the outputs to an LCD display. All this using Raspberry PI GPIO pins and Python threads."
Thank you, your explaining so easy understand.
ReplyDeleteThis tutorial has been extremely helpful, Thank You Very Much, Rob.
ReplyDeleteThis is exactly what I needed for my application- Which is to build a rover using Raspberry Pi and the threads would help me to distribute the workload keeping my Pi from the risk of falling to pieces due to workload.
You Rock Rob.
Excellent Tutorial!
ReplyDeleteThis comment has been removed by a blog administrator.
ReplyDeleteVery easy to underestand with your explenation. Thanks
ReplyDeleteRob, great tutorial. I have a question: Is the sleep in each of the threads including the main program required to allow the other threads to execute? My application involves monitoring voltages, displaying it on the screen AND reporting over/under voltage events via email. My problem currently is that sending the email will freeze the program for up to 10 seconds while no updates can be done. If I push the email sending to a thread, will the main program retain execution to continue monitoring and not have to wait for the email send to complete?
ReplyDeleteThanks so much. Really Appreciate it.
ReplyDeleteFinally threading is making sense. Thankyou
ReplyDeleteIf I start the programm its mean:
ReplyDeleteTraceback (most recent call last):
File "/home/pi/PythonProjeke/youtube-dl.py", line 1, in
import os, thearding
ModuleNotFoundError: No module named 'thearding'
Can you help me?
Awesome explanation and tutorial. I've 39 years of software development experience but I'm new to Pi, python and programing GPIOs (been coding business applications - accounting, payroll, etc). Bob you are gifted at imparting knowledge. You are one to follow.
ReplyDeleteThank you Rob, I had a problem reading a PIR sensor in my program and the IRQ routine was too long to be reliable. I came across your page, and gave threading a try - first time....In an hour I had solved my problem thanks to your excellent explanation and example! Thank you very much! Steven in Canada
ReplyDelete