Tuesday, 26 January 2016

Raspberry Pi - Python Threading

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 :)"

2 comments:

  1. Thank You so much for explaining it so well. Can you please share the code for the understated:
    "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."

    ReplyDelete
  2. Thank you, your explaining so easy understand.

    ReplyDelete

Thank you fro reading my page.
Let me know if there is anything that I could add or change.
Please let me know if this information is helpful.